If you need it in Python 3.x, see my other answer - a closure cell __class__is all you need.
If you need to do this in CPython 2.6-2.7, RickyA's answer is close, but it does not work, because it relies on the fact that this method does not override any other method with the same name. Try adding a method Foo.do_itto your answer and it will print Foo, notSomeClass
, :
def do_it(self):
mro = inspect.getmro(self.__class__)
method_code = inspect.currentframe().f_code
method_name = method_code.co_name
for base in reversed(mro):
try:
if getattr(base, method_name).func_code is method_code:
print(base.__name__)
break
except AttributeError:
pass
( , AttributeError base, - do_it, base - do_it, , , , a func_code. , base , .)
Python 2.6+. Python , , , inspect.currentframe() None. , , , func_code None.
, 2.7+, 3.0+, func_code __code__, 2.x.
CPython 2.5 , inpsect CPython :
def do_it(self):
mro = self.__class__.mro()
method_code = sys._getframe().f_code
method_name = method_code.co_name
for base in reversed(mro):
try:
if getattr(base, method_name).func_code is method_code:
print(base.__name__)
break
except AttributeError:
pass
, mro() ; ( ...), mro, ... 2.6 inspect .
Python 2.x, , CPython... PyPy. inspect , , frame code , CPython, inspect, sys._getframe ...