Using metaclasses to inherit class variables
Steven Bethard
steven.bethard at gmail.com
Mon May 22 13:12:06 EDT 2006
telesphore4 at gmail.com wrote:
> OK no question. I'm only posting b/c it may be something another newbie
> will want to google in the future. Now that I've worked thru the
> process this turns out to be fairly easy.
>
> However, if there are better ways please let me know.
>
> Module = ClassVars.py
>
> import copy
>
> class ClassVars(type):
> classVars = {}
> def __init__(cls, name, bases, dict):
> for name, value in type(cls).classVars.iteritems():
> if name not in dict:
> setattr(cls, name, copy.copy(value))
>
> count = 0 # Not really needed but it semed nice to name the new types
> def are(dict):
> global count
> count += 1
> return type('ClassVars%d' % count, (ClassVars,),
> {'classVars':dict})
>
>
> To use in another module:
>
> import ClassVars
>
> class MyClass(str):
> __metaclass__ = ClassVars.are(dict(name=None, desc=None,
> myList=[]))
>
> # Rest of class definition ...
Hmm... That still seems more complicated than you need. I think you
really want to be able to write something like:
class C(object):
__metaclass__ = set_classvars(name=None, desc=None, myList=[])
Which is actually quite easily done with nested functions:
>>> def set_classvars(**kwargs):
... def __metaclass__(name, bases, classdict):
... for name, value in kwargs.iteritems():
... if name not in classdict:
... classdict[name] = value
... return type(name, bases, classdict)
... return __metaclass__
...
>>> class C(object):
... __metaclass__ = set_classvars(name='foo', desc='bar', list=[])
... name = 'not foo'
...
>>> C.name, C.desc, C.list
('not foo', 'bar', [])
>>> class D(C):
... __metaclass__ = set_classvars(name='foo', list=[])
...
>>> D.name, D.desc, D.list, D.list is C.list
('foo', 'bar', [], False)
STeVe
More information about the Python-list
mailing list