Metaclasses

Robert Brewer fumanchu at amor.org
Thu Dec 23 17:42:28 EST 2004


Bob Cowdery wrote:
> Thanks for your help Robert. I'm still not
> understanding what I am seeing. I've forgotten
> about the objective for the moment. I just want
> to understand metaclasses.

All right; then I'll skip the speech about how metaclasses are not the solution you're looking for. ;) They rarely are.

> Two things I don't understand. __init__ gets called
> when I import api, not when I create an instance of
> API so the capability is set in stone on the import
> and I can't change it.

Correct. autoprop.__init__ is executed when the API class definition has finished executing. This is an important point about Python in general: class definitions are not declared so much as executed. Your API class, for example, has three statements that happen to be executed within the scope of a class definition; otherwise, they're normal Python statements and are executed like any other. The statements in autoprop.__init__ are executed after the last statement in the API class definition has executed.

Anyway, if you want your code (which binds capability methods) to occur per-instance, it should most likely be executed within API.__init__, and you don't need metaclasses at all. autoprop.__init__ is executed once per *class*, not once per instance. That is, if someone were to make a subclass of API, then autoprop.__init__ would fire again, receiving that subclass instead of the API class as its first argument.

> Second when I try to read attribute 'mode'
> (or any other valid attribute) I get an error.
> If I set it to some value and read it it's there.

When you set the value, you're not going through the property--it's just setting a new attribute on the object as you can with any Python object.

>>> class Thing(object): pass
... 
>>> t = Thing()
>>> t.stuff = 4, 5, 6
>>> t.stuff
(4, 5, 6)

I think the first thing you need to do is stop using __private members, which mangle their own names. ;) Drop them, get your metaclass (or other solution) working, then go back to __private names if you want. At the moment, it's confusing the issue greatly.

But why don't you just dynamically set attributes (like 'mode') instead of methods (like '_get_mode')? Will some of these be read-only?


Robert Brewer
MIS
Amor Ministries
fumanchu at amor.org



More information about the Python-list mailing list