__在Python中约束属性创建的setattr_uu_uu_uu_uuu_uu_uuu_2;

2024-10-04 03:24:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在阅读如何降低Python类的动态性,特别是不允许用户动态创建新属性。我读过overloadding ^{} is a good way to do this,和{a2}。其中一个post on this last thread实际上表明__slots__可以破坏酸洗。(有人能证实吗?)在

但是,我刚刚在阅读python2.2的whatsnew,the attribute access section实际上建议使用__slots__来约束属性创建,而不仅仅是像其他人建议的那样用于优化。从Python的历史来看,有人知道__slots__的初衷是什么吗?约束变量的创建是一个特性还是一个被滥用的bug?人们是如何看待__slots__在实践中使用的?是否有许多人见过__setattr__重载以限制属性创建?哪一个最好?如果你对一种方法或另一种方法比较熟悉,请随时发表你所知道的方法的利弊。另外,如果你有不同的解决问题的方法,请分享!(请尽量不要重复__slots__中表达的__slots__的缺点。)

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

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

编辑3:我还应该提一下,保存记忆不是问题。只有很少的对象会被创建,所以节省的任何内存都可以忽略不计(比如在一台3-12GB的机器上,内存是10s千字节)。在


Tags: 对象方法内存用户程序编辑参数属性
2条回答

你为什么要限制开发者这么做?除了“我不想让他们这么做”之外,还有什么技术原因吗?如果没有,就不要做。在

总之,使用__slots__可以节省内存(不是__dict__),因此这是更好的解决方案。但是,如果某些代码需要对象具有__dict__,则无法使用它。在

如果有一个很好的理由限制它(同样,你确定有一个吗?)或者你需要节省一点内存,去__slots__。在


{{cd5>在阅读之后,你可能需要使用whitelist来保存它。这样您就可以显示一些更有用的信息,例如哪些类似的属性可用。可能的实现方式如下:

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__方法的mixin类来进一步改进代码。这样,您就可以将代码排除在实际类之外,如果需要,还可以使用自定义的__setattr__(只需在mixin中使用super(...).__setattr__(...),而不是object.__setattr__

我对您的用例的建议是使用__setattr__并在使用Python的warnings模块无法识别属性名时发出一个警告。在

相关问题 更多 >