代码之家  ›  专栏  ›  技术社区  ›  Nick Heiner

python:类可以禁止客户端设置新属性吗?

  •  12
  • Nick Heiner  · 技术社区  · 14 年前

    我花了太长时间在一个bug上,比如:

    >>> class Odp():
        def __init__(self):
            self.foo = "bar"
    
    
    >>> o = Odp()
    >>> o.raw_foo = 3 # oops - meant o.foo
    

    我有一个具有属性的类。我试着设置它,想知道为什么它没有效果。然后,我回到最初的类定义,看到属性的命名略有不同。因此,我创建/设置了一个新属性,而不是一个想要的属性。

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

    第二,我有没有办法在定义时禁止这样做? Odp 这样就省去了麻烦?

    1 回复  |  直到 14 年前
        1
  •  21
  •   Alex Martelli    14 年前

    您可以实现 __setattr__ 方法——比 __slots__ 这通常被误用于目的(例如, _插槽__ 当类从继承时自动“丢失”,而 _塞塔特__ 除非明确重写,否则生存)。

    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__ 方法而不是直接属性分配。(禁止在 而不是它 实例 您必须使用类似的特殊方法定义自定义元类)。