【发布时间】:2013-12-22 18:27:39
【问题描述】:
我一直在阅读有关如何使 Python 类不那么动态的文章,特别是不允许用户动态创建新属性。我读过overloadding __setattr__ is a good way to do this 和__slots__ is not the way to go。一位post on this last thread 实际上建议__slots__ 可以破坏酸洗。 (谁能证实这一点?)
但是,我只是在阅读 Python 2.2 的最新消息,the attribute access section 实际上建议使用__slots__ 来限制属性创建,而不仅仅是像其他人建议的那样进行优化。就Python历史来说,有谁知道__slots__的初衷是什么?约束变量创建是要被滥用的功能还是错误?人们如何看待__slots__ 在实践中的使用?有很多人看到__setattr__ 重载以限制属性创建吗?哪个最好?如果您更熟悉一种方法或另一种方法,请随时发布您所知道的方法的优缺点。另外,如果您有其他解决问题的方法,请分享! (请尽量不要重复__slots__ 的缺点,这些缺点已在other threads 中表达。)
编辑:我希望避免讨论“为什么?”,但第一个答案表明这会出现,所以我会在这里说明。在有问题的项目中,我们使用这些类来存储“配置信息”,允许用户使用他们的(用户的)参数设置对象的属性,然后将对象传递给程序的另一部分。对象不仅仅是存储参数,所以字典不起作用。我们已经让用户不小心输入了错误的属性名称,最终创建了一个新属性,而不是设置程序期望的属性之一。这未被检测到,因此用户认为他们正在设置参数但没有看到预期的结果。这让用户感到困惑,而且很难发现。通过约束属性创建,将抛出异常而不是静默通过。
编辑2,重新酸洗:这些对象将是我们将来想要存储的东西,酸洗似乎是一种很好的方法。如果__slots__ 显然是最好的解决方案,我们可能会找到另一种存储它们的方法,但酸洗肯定是有价值的,应该考虑在内。
编辑 3:我还应该提到,内存保护不是问题。很少会创建这些对象,因此节省的任何内存都可以忽略不计(例如 3-12 GB 机器上的 10 千字节)。
【问题讨论】:
-
我相信插槽的目的是(并且仍在使用)使类实例的内存占用更小。
-
只需使用
__slots__,它可以满足您的需求并节省内存,这很好 -
@piokuc -- 但它会破坏酸洗和其他任何依赖于具有已定义
__dict__的对象的东西,这并不完全不常见。此处的实际建议必须由 OP 打算使用此类来确定。当然,一个更公平的问题是为什么 OP 首先要限制属性创建?我们在这里都是成年人…… -
@mgilson 我同意了解更多关于特定类及其用途的信息会很有用,即并非每个对象都需要腌制
-
@mgilson 我添加了我为什么要约束属性创建的描述。作为一个普遍的问题,为什么这么多人似乎反对这一点?我意识到 Python 是一种动态语言,但很少有时候我想为现有对象添加新属性。许多库,例如 Numpy,不允许您向它们的类添加属性(我试过)。也许我只是有这种感觉,因为我来自 OOP 背景。
标签: python attributes slots setattr