gpt4 book ai didi

python - __setattr__ 与 __slots__ 用于约束 Python 中的属性创建

转载 作者:太空宇宙 更新时间:2023-11-04 09:06:24 31 4
gpt4 key购买 nike

我一直在阅读如何使 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__重载来限制属性创建吗?哪个最好?如果您更熟悉一种或另一种方法,请随时发表您所知道的方法的优缺点。另外,如果您有其他解决问题的方法,请分享! (并且请尽量不要重复在 other threads 中表达的 __slots__ 的缺点。)

编辑:我希望避免讨论“为什么?”,但第一个答案表明这会出现,所以我会在这里说明。在相关项目中,我们使用这些类来存储“配置信息”,允许用户使用他们(用户)的参数设置对象的属性,然后将对象传递给程序的另一部分。这些对象不仅仅是存储参数,所以字典是行不通的。我们已经让用户不小心输入了错误的属性名称,并最终创建了一个新属性,而不是设置程序期望的属性之一。这未被发现,因此用户认为他们正在设置参数但没有看到预期的结果。这会让用户感到困惑,并且很难发现。通过限制属性的创建,异常将被抛出而不是默默地通过。

编辑 2,重新酸洗:这些对象将是我们将来要存储的东西,酸洗似乎是一个很好的方法。如果 __slots__ 显然是最好的解决方案,我们可能会找到另一种方法来存储它们,但是 pickling 肯定是有值(value)的,应该考虑在内。

编辑 3:我还应该提到内存保护不是问题。这些对象中很少会被创建,因此任何节省的内存都可以忽略不计(例如 3-12 GB 机器上的 10 千字节)。

最佳答案

您为什么要限制开发人员这样做?除了“我不想让他们这样做”之外,还有什么技术原因吗?如果没有,请不要这样做。

无论如何,使用 __slots__ 可以节省内存(没有 __dict__)所以这是更好的解决方案。但是,如果您的某些代码需要该对象具有 __dict__,您将无法使用它。

如果有充分的理由限制它(再一次,你确定有一个吗?)或者你需要节省那一点内存,去__slots__.


阅读您的解释后,您可能想使用 __setattr__,可能与 __slots__ 结合使用(无论如何您都需要将属性白名单存储在某处,因此您也可以使用它以节省内存)。这样您就可以显示一些更有用的信息,例如哪些similar 属性可用。一个可能的实现可能是这样的:

class Test(object):
__slots__ = ('foo', 'bar', 'moo', 'meow', 'foobar')

def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)
except AttributeError:
alts = sorted(self.__slots__, key=lambda x: levenshtein(name, x))
msg = "object has no attribute '{}', did you mean '{}'?"
raise AttributeError(msg.format(name, alts[0]))

我测试的 levenshtein() 是来自 this site 的实现#4 .对于不太聪明的用户,您可能希望使错误更加详细并包括所有接近的匹配项,而不仅仅是第一个。

您可以通过创建仅包含 __setattr__ 方法的混合类来进一步改进代码。这样您就可以将代码保留在您的真实类之外,并且在必要时还可以自定义 __setattr__ (只需使用 super(...).__setattr__(...)在 mixin 而不是 object.__setattr__)

关于python - __setattr__ 与 __slots__ 用于约束 Python 中的属性创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20406363/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com