Python dynamic attribute creation

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Jun 25 12:25:14 EDT 2010


On Fri, 25 Jun 2010 14:15:12 +0100, WANG Cong wrote:

> 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.

Yes, isn't it wonderful? In other languages, metaprogramming is deepest 
black magic, or even completely impossible. In Python it is so easy that 
anyone can do it, and it is something beginners learn.


> 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++.

Why should it be?


> 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.

Why do you care if you are doing metaprogramming? Perhaps other languages 
make it seem difficult and scary, but in Python it is not. It is simple 
and easy.


> 4) Also, this will _somewhat_ violate the OOP princples, in OOP, this is
> and should be implemented by inherence.

Perhaps, and perhaps not. But Python has never pretended to slavishly 
follow OOP "principles". Python does what works, not necessarily what is 
a "pure" design. Python has functional programming, procedural 
programming, and OO programming, and happily mixes them all together.


> 5) This could hide errors silently, for example, when I do:
> 
>>>>test.typooooo = "blah"

Yes, that is one downside to Python's dynamicism. The solutions are:

* Unit tests, unit tests, unit tests. Then more unit tests.
  (You're writing them anyway, aren't you?)
* Run PyChecker or PyLint to check the source code for errors.
* Don't make typos. *smiles*


> 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?!

Then don't do that.


> 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_,

There are many languages that do that. Python is not one of them. Python 
is *designed* to be a dynamic language. If you don't like dynamic 
languages, then you have many, many, many other choices. Perhaps such a 
language is better for *you*. Perhaps such non-dynamic languages are 
better for huge applications written by thousands of developers. But 
Python is designed to be a rapid prototyping language, and as such, 
dynamicism is a feature, not a bug.



-- 
Steven



More information about the Python-list mailing list