Python: Can a class forbid clients setting new attributes?

前端 未结 1 1648
猫巷女王i
猫巷女王i 2021-01-01 23:52

I just spent too long on a bug like the following:

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


>>> o = Odp()
>         


        
1条回答
  •  囚心锁ツ
    2021-01-02 00:07

    You can implement a __setattr__ method for the purpose -- that's much more robust than the __slots__ which is often misused for the purpose (for example, __slots__ is automatically "lost" when the class is inherited from, while __setattr__ survives unless explicitly overridden).

    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__))
    

    You'll have to make sure the hasattr succeeds for the names you do want to be able to set, for example by setting the attributes at a class level or by using object.__setattr__ in your __init__ method rather than direct attribute assignment. (To forbid setting attributes on a class rather than its instances you'll have to define a custom metaclass with a similar special method).

    0 讨论(0)
提交回复
热议问题