Python Dynamic Attributes – Blessing or Curse?

python

Consider this code:

>>> class Foo():
        pass
...
>>> foo = Foo()
>>> foo.a = 'test'
>>> foo.a
'test'

One can just override __setattr__ to make attributes read only and prevent their creation at runtime, however:

  • Why is this the default Python behavior (any good reasons)?
  • Is there any practice to prevent this without altering each class?
  • Would you worry about this behavior in serious projects? don't you consider it error prone? or you can just ignore it (relying on new IDEs code completion)

Best Answer

As others already mentioned, preventing this would require a special case for __init__, and one of the design principles of Python is to avoid special cases, see the Zen of Python:

Special cases aren't special enough to break the rules.

This design is also in line with other design decisions, e.g, the lack of static type checking or access control modifiers. Python tends to empower its users, not to enforce things.

You can easily prevent this for any particular class by using __slots__. However, there is no way to change this globally.

While this can in theory cause errors, I wouldn't worry about it much. For example, a typo could mean that you are by accident create a new attribute when you meant to assign to an existing attribute. However, good unit testing coverage will usually catch this.