【问题标题】:Python: Can a class forbid clients setting new attributes?Python:一个类可以禁止客户端设置新属性吗?
【发布时间】:2010-06-29 02:58:31
【问题描述】:

我只是在如下错误上花费了太长时间:

>>> class Odp():
    def __init__(self):
        self.foo = "bar"


>>> o = Odp()
>>> o.raw_foo = 3 # oops - meant o.foo

我有一个带有属性的类。我试图设置它,并想知道为什么它没有效果。然后,我回到原来的类定义,发现属性的名称稍有不同。因此,我正在创建/设置一个新属性,而不是原本的属性。

首先,这不正是静态类型语言应该防止的错误类型吗?在这种情况下,动态类型的优势是什么?

其次,有没有什么方法可以在定义Odp时禁止它,从而省去自己的麻烦?

【问题讨论】:

标签: python oop typing


【解决方案1】:

您可以为此目的实现__setattr__ 方法——这比经常被滥用的__slots__ 更健壮(例如,当类继承自时,__slots__ 会自动“丢失” , 而__setattr__ 除非被明确覆盖,否则仍然存在)。

def __setattr__(self, name, value):
  if hasattr(self, name):
    object.__setattr__(self, name, value)
  else:
    raise TypeError('Cannot set name %r on object of type %s' % (
                    name, self.__class__.__name__))

您必须确保 hasattr 对您希望能够设置的名称成功,例如通过在类级别设置属性或使用 object.__setattr__在您的 __init__ 方法中,而不是直接分配属性。 (要禁止在 class 而不是它的 instances 上设置属性,您必须使用类似的特殊方法定义自定义元类。

【讨论】:

  • 为什么选择TypeError?也许是错误的,我想到了AttributeError
  • “不支持 XX 分配”消息(例如项目)使用 TypeError,更容易混淆的措辞“没有 XX 属性”使用 AttributeError,所以我猜两者都可以(尽管两者都没有)非常完美)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 2014-02-12
  • 2012-03-06
相关资源
最近更新 更多