6

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)
asked Aug 31, 2013 at 12:35
6
  • 1
    What other default behaviour would you expect, and what consequences would it have for class definitions, in particular __init__? Commented Aug 31, 2013 at 12:44
  • @delnan I would expect AttributeError: 'Foo' object has no attribute 'a' consequences may be in typing, you can for example type: foo.pasword = 'something' instead of foo.password = 'something' Commented Aug 31, 2013 at 13:00
  • 2
    @01walid: What delnan means is that there is no difference between self.a = 'test' in the __init__ method and foo.a on the instance. Both self and foo are just references to the instance. Commented Aug 31, 2013 at 13:02
  • Ok but, at least -for me- in __init__ you're still inside the class declaring its attributes, I'm asking why the same behavior outside the class definition as for an instance of it? Commented Aug 31, 2013 at 13:13
  • 2
    @01walid: You can define the __init__ outside the class and then add a reference to it to the class; it'll work just the same as if it was part of the class definition. Python is a highly dynamic language. Commented Aug 31, 2013 at 13:15

2 Answers 2

7

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.

answered Sep 1, 2013 at 12:32
2

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)

Yes, I worry. To me, it is not clear from the post whether you are pointing to the dangers of allowing outsiders to reason about and change the structure of the objects, or to the dangers of assigning to a previously undefined attribute. However, both behaviors are known to be problematic (the first, for sacrificing the benefits information hiding techniques bring to the table and relying on convention; the latter for allowing the spreading of definitions of structure/object when it is desired to have them locally organized).

answered Aug 31, 2013 at 18:58

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.