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