Python dynamic attribute creation
WANG Cong
xiyou.wangcong at gmail.com
Fri Jun 25 09:15:12 EDT 2010
Hi, list!
I have a doubt about the design of dynamic attribute creation by
assignments in Python.
As we know, in Python, we are able to create a new attribute of
a class dynamically by an assignment:
>>> class test: pass
...
>>> test.a = "hello"
>>> test.a
'hello'
>>>
However, I still don't get the points why Python designs it like this.
My points are:
1) Modifying a class attribute is metaprogramming, and this is modifying
a class, i.e. adding a new attribute to it, thus this should belong
to metaprogramming. (I know, strictly speaking, maybe my definition of
"metaprogramming" here is incorrect, I _do_ welcome someone could
correct me if I am really wrong, but that is not the main point here,
please don't go off-topic.)
2) Metaprogramming should be distinguished with non-meta programming,
like templates in C++, it is obvious to see if you are using template
metaprogramming in C++.
3) Thus, allowing dynamic attribute creation by assignment _by default_
is not a good design for me. It is not obvious at all to see if I am
doing metaprogramming at a first glance.
4) Also, this will _somewhat_ violate the OOP princples, in OOP,
this is and should be implemented by inherence.
5) This could hide errors silently, for example, when I do:
>>>test.typooooo = "blah"
I am expecting Python will compllain that "Hey! You have a typo in the
attribute name!". Also, this could make code worse to read, if I
add a new attribute in one place, and add another one in the another
place, and so on, what attributes the hell do I have finally?!
I know someone will say you can change this by overriding the
__set_attr__ function, like Recipe 6.3 in Python Cookbook.
However, this is not default. In my points of view, a better design
should be:
1) Disallow dynamic attribute creations by assignments _by default_,
thus I expect an error when I do:
>>> foo.new_attr = "blah"
AttributeError:
by default.
2) For people who want to add a new attribute at runtime,
but not to override __set_attr__, he/she should switch to:
>>> setattr(foo, "new_attr", "blah")
This will be more like doing metaprogramming rather than non-meta
programming, at least more obvious than using an assignment.
3) Allow users who don't like this to change by __set_attr__,
of course.
Someone argued with me that Python is a dynamic language,
allowing this is natural. True, I do understand that attributes in
Python are stored in an internal dictionary (__dict__), allowing
assignments to an non-existing key is natural. However, this will be
a little different when we talk about classes attributes, simple
assignments could have side-effects, besides the traditional assignments
effect, like in C, that is, creating a new attribute silently. So even
from a view of beauty, this is not a good design.
I hope someone could teach me more about why Python design it like
it is. Any reply is more than welcome.
Thanks for your time!
--
Live like a child, think like the god.
More information about the Python-list
mailing list