Getting current class in method call
class A:
def x ( self ):
print( self.__class__ )
class B ( A ):
pass
b = B()
b.x()
In the above situation, is there any way for the method x
to get a reference to class A
instead of B
? Of course simply writing print( A )
is not allowed, as I want to add some functionality with a decorator th开发者_如何学运维at needs the class A
(and as I can't pass A itself to the decorator directly, as the class doesn't exist yet at that point).
Unless you have super
-calls involved (or more generally subclasses that override x
and call directly to A.x(self)
as part of their override's implementation), looking for the first item in type(self).mro()
that has an x
attribute would work --
next(c for c in type(self).mro() if hasattr(c, 'x'))
If you do need to cover for super
-calls, it's harder -- unless you happen to know that no super-class of A
defines an x
attribute (and of course it's easier to know about your superclasses than your subclasses, though multiple inheritance does complicate it;-) in which case you only need the last appropriate item of the mro
instead of the first one.
You can use name mangling to associate the class a method is defined in with a method:
def set_defining_class(cls):
setattr(cls, '_%s__defining_class' % (cls.__name__,), cls)
return cls
@set_defining_class
class A(object):
def x (self):
print(self.__defining_class)
@set_defining_class
class B ( A ):
pass
b = B()
b.x()
Done here with a class decorator, but you could do it by hand, or in a metaclass too.
精彩评论