[Python-3000] Fixing super anyone?
Steven Bethard
steven.bethard at gmail.com
Wed Apr 25 07:26:37 CEST 2007
On 4/24/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> On 4/24/07, Calvin Spealman <ironfroggy at gmail.com> wrote:
> > I must have miscopied then because it worked perfectly here. Yes, I
> > meant to have the _superdesc defined inside the metaclass __init__,
> > but thought I could pull it out to make it cleaner. I forgot it
> > actually had to be there! Here is the metaclass that works.
> >
> > class autosuper(type):
> > def __init__(cls, name, bases, clsdict):
> > class _superdesc(object):
> > def __get__(self, obj, objcls):
> > return super(cls, obj)
> > cls.__super__ = _superdesc()
>
> I still get the same error.
I played around with this for a while. Below is some code that does
work. The trick is to redefine super() so that when you're calling
__get__ to bind a method to an instance, you bind it to the Super()
instance, not the original object instance.
class Super(object):
def __init__(self, type, obj=None):
if isinstance(obj, Super):
obj = obj.__obj__
self.__type__ = type
self.__obj__ = obj
def __get__(self, obj, cls=None):
if obj is None:
raise Exception('only supports instances')
else:
return Super(self.__type__, obj)
def __getattr__(self, attr):
mro = iter(self.__obj__.__class__.__mro__)
for cls in mro:
if cls is self.__type__:
break
for cls in mro:
if attr in cls.__dict__:
x = cls.__dict__[attr]
if hasattr(x, '__get__'):
x = x.__get__(self, cls)
return x
raise AttributeError, attr
class autosuper(type):
def __init__(cls, name, bases, clsdict):
cls.__super__ = Super(cls)
class A:
__metaclass__ = autosuper
def f(self):
return 'A'
class B(A):
def f(self):
return 'B' + self.__super__.f()
class C(A):
def f(self):
return 'C' + self.__super__.f()
class D(B, C):
def f(self):
return 'D' + self.__super__.f()
assert D().f() == 'DBCA'
See ma, no bytecode hacks! ;-)
STeVe
--
I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
--- Bucky Katt, Get Fuzzy
More information about the Python-3000
mailing list