is (should) it (be) a reserved word?
Roeland Rengelink
r.b.rigilink at cable.a2000.nl
Mon Oct 9 20:32:30 EDT 2000
More information about the Python-list mailing list
Mon Oct 9 20:32:30 EDT 2000
- Previous message (by thread): super - is (should) it (be) a reserved word?
- Next message (by thread): super - is (should) it (be) a reserved word?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Grant Edwards wrote: > > In article <mailman.971064623.25775.python-list at python.org>, Michal Wallace wrote: > > >> Alex Martelli wrote: > >> > > >> > self.__class__.__bases__[0] satisfies this request, I think. > >> > >> Not when there is more than one level of inheritance > >> involved. The class you want to find the base class > >> of isn't the class of self, it's the class where the > >> currently executing method was defined, and there's > >> currently nothing in Python that keeps track of that. > > Excellent point. I should have thought of that. > > >Why do you need that? Calling a method of a class > >climbs the hierarchy for you, all the way up to where > >the method was first defined or last overridden. > > The example I most often run into is in an __init__ method > where I want to initialize the features my subclass is adding > and then pass control and the remaining arguments on up to the > __init__ method one layer up. The "super" that I want access > to is the parent of the class containing the reference to > "super", not the parent of the class of "self". > I think this is close to what you're looking for, although I strongly recommend using standard idiom to solve standard problems. i.e. use: class A(B): def __init__(self): B.__init__(self) or any of its variants. Roeland -- import types, sys class SuperCaller: '''SuperCaller() class that allows one to write super.do(self) as a smart version of self.__class__.bases[0].do(self): It is smart in the sense that 'do' is searched for among the complete inherentance hierarchy (depth first). The search is started in the class that defined the method that invokes super.do(), not in the class from which self was instantiated. E.g: name-resolution works the same way as with inheritance. (see tets() for an example). You can do: class AClass: def do(self): print 'Hi', class BClass(AClass): def do(self): super.do(self) print 'Ho', class CClass(BClass): def do(self): super.do(self) print 'He' and expect CClass().do() to result in Hi Ho He needs super = SuperCaller() to be defined in *Class' namespace Violates "explicit is better than implicit" in the most horrible way!''' method_name = None calling_code = None def __getattr__(self, method): # What do we want to call, and what wants to do it? SuperCaller.method_name = method try: raise Exception except Exception: frame = sys.exc_info()[2].tb_frame.f_back SuperCaller.calling_code = frame.f_code return self.super_caller def __repr__(self): return '<SuperCaller>' def find_calling_class(self, cls): '''find out what the class is from which SuperCaller.calling_code was calling super.method()''' for val in cls.__dict__.values(): if (type(val) == types.FunctionType and val.func_code == SuperCaller.calling_code): return cls for super in cls.__bases__: cls = self.find_calling_class(super) if cls: return cls def find_method(self, cls): '''find self.method among the bases of class cls''' for super_cls in cls.__bases__: if super_cls.__dict__.has_key(SuperCaller.method_name): return super_cls.__dict__[SuperCaller.method_name] method = self.find_method(super_cls) if method: return method def super_caller(self, *pars, **kw): # pars[0] is an instance # First find the calling class, then find a method among its bases cls = self.find_calling_class(pars[0].__class__) meth = self.find_method(cls) if not(meth): raise AttributeError, "No method %s in bases of %s" % \ (SuperCaller.method_name, pars[0].__class__) # In 2.0: return meth(*pars, **kw) return apply(meth, pars, kw) super = SuperCaller() def test(): class A: def __init__(self): print 'A.__init__ called by', self class B(A): def __init__(self): super.__init__(self) # A.__init__ print 'B.__init__ called by', self class C(B): pass class D(C): def __init__(self): super.__init__(self) # B.__init__ print 'D.__init__ called by', self class E: pass class F(E, D): def __init__(self): super.__init__(self) # D.__init__ print 'F.__init__ called by', self print 'Constructing F' F() if __name__ == '__main__': test()
- Previous message (by thread): super - is (should) it (be) a reserved word?
- Next message (by thread): super - is (should) it (be) a reserved word?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list