开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜