Question about accessing class-attributes.
Michele Simionato
mis6 at pitt.edu
Fri Apr 25 14:00:47 EDT 2003
Michael Hudson <mwh at python.net> wrote in message news:<7h3bryulp3e.fsf at pc150.maths.bris.ac.uk>...
> mis6 at pitt.edu (Michele Simionato) writes:
>
> > The meta-type conflict is rather annoying, indeed. According to the
> > metaclass book, the language should generate the correct metaclass
> > that solves the conflict automatically, without burden for the
> > programmer. Python is not that magic (yet) therefore you have to
> > solve the conflict yourself.
>
> I guess a potential problem is that if you do
>
> class C(object):
> __metaclass__ = A
>
> class D(object):
> __metaclass__ = B
>
> class E(C, D):
> pass
>
> class F(C, D):
> pass
>
> you'd like both E and F to have the *same* (rather than merely
> equivalent) metaclasses. This would seem to be tricky to arrange.
>
> Cheers,
> M.
Yes, but I didn't posted my full solution ;)
I take a list of all generated metaclasses and I reuse them:
def withmemory(f):
"""This closure remembers all f invocations"""
argskw=[]; result=[]
def _(*args,**kw):
akw=args,kw
try: # returns a previously stored result
i=argskw.index(akw)
except ValueError: # there is no previously stored result
res=f(*args,**kw) # returns the new result
argskw.append(akw) # update argskw
result.append(res) # update result
return res
else:
return result[i]
_.argskw=argskw #makes the argskw list accessible outside
_.result=result #makes the result list accessible outside
return _
_generatemetaclass=withmemory(_generatemetaclass)
Now, when _generatemetaclass is invoked with the same bases it returns the
same metaclass:
>>> class A(type): pass
...
>>> class B(type): pass
...
>>> class C: __metaclass__=A
...
>>> class D: __metaclass__=B
...
>>> E=child(C,D,name='E')
>>> type(E)
<class 'oopp._AB'>
>>> F=child(C,D,name='F')
>>> type(F)
<class 'oopp._AB'>
>>> type(E) is type(F)
True
It works enough for me ;)
Michele
More information about the Python-list
mailing list