Python dynamic attribute creation

Richard Thomas chardster at gmail.com
Fri Jun 25 09:31:33 EDT 2010


On Jun 25, 2:15 pm, WANG Cong <xiyou.wangc... at gmail.com> 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. (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.

If you desperately want to limit the attribute assignments that can be
performed on an object you can set the __slots__ attribute of its
type. However, the Python ethos has always been to restrict as little
as necessary to provide the tools it needs. Performing additional
checks every time an attribute assignment is performed is completely
unnecessary. Remember that unlike C these checks would have to be
performed at run-time.

Richard.



More information about the Python-list mailing list