python - 为什么同一类的两个实例具有不同的属性(Python)是明智的?
问题描述
class Stock:
... def __init__(self, ticker, price):
... self.ticker = ticker
... self.price = price
...
>>> apple = Stock('APPL', 100)
>>> apple.ceo='tim cook'
>>> google = Stock('GOOG', 10)
现在如果你比较dir(apple)
并且实例dir(google)
将apple
有一个额外的属性ceo
。
然而,isinstance(apple,Stock)
两者isinstance(google,Stock)
都是真实的。
允许具有不同属性的对象都成为同一类的实例背后的直觉是什么?你什么时候用这个,实际上?
我会认为作为同一类实例的对象必须具有相同的属性列表。
解决方案
它通常没有用,也不鼓励使用,既出于风格原因,又因为(在 CPython 中)它使每个实例使用更多内存(通过破坏密钥共享字典)。
当它出现时,它通常用于缓存(计算一些可能并不总是使用的值很昂贵,但如果计算它以供重用,则应该存储它),或者在对象主要充当字符串键字典的情况下具有属性访问语义,类似于 JSON 对象(types.SimpleNamespace
适用于大多数此类情况)。
为了启用这些(诚然不常见的)用例,大多数 Python 对象将它们的属性存储在dict
引擎盖下,并且它们不会(太多)区分分配时间__init__
和其他时间。
如果你不想要这个特性,你可以通过在你的类上定义__slots__
来明确地描述合法属性来禁用任意属性的创建;这将防止创建任何其他属性,并进一步减少类的每个实例的内存使用量(甚至比键共享字典所能做的更多)。在你的情况下,你会这样做:
class Stock:
__slots__ = 'ticker', 'price'
def __init__(self, ticker, price):
self.ticker = ticker
self.price = price
推荐阅读
- docker - FROM...AS 在 Dockerfile 中没有按我的预期工作
- doctrine-orm - 如何更改创建实体的默认位置?(php bin/控制台制作:实体)
- timestamp - 如何在grafana中将字符串时间戳列转换为时间戳
- tensorflow - 在 tensorflow 或 keras 中通过标准 mobileNet、VGG-16 或 AlexNet 从头开始训练 cifar 日期集的图像大小问题
- android - Android 应用程序中 webRTC 通话期间的录音
- android - RecyclerView 展开/折叠太快
- c# - 使用浏览器浏览服务器上的本地文件夹。有点像使用 file://
- azure - 通过 Powershell 在 EA 门户中将服务主体激活为帐户所有者?
- r - 是否有一个 R 函数可以将其中带有随机字母的序列识别为唯一的?
- angular - 可观察对象在访问之前未完全初始化