Jes*_*dge 77 python python-2.6 python-datamodel
如何获得在Python中定义方法的类?
我想要以下示例打印" __main__.FooClass
":
class FooClass:
def foo_method(self):
print "foo"
class BarClass(FooClass):
pass
bar = BarClass()
print get_class_that_defined_method(bar.foo_method)
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 64
import inspect
def get_class_that_defined_method(meth):
for cls in inspect.getmro(meth.im_class):
if meth.__name__ in cls.__dict__:
return cls
return None
Run Code Online (Sandbox Code Playgroud)
感谢Sr2222指出我错过了这一点......
这是纠正的方法,就像亚历克斯一样,但不需要输入任何东西.我不认为这是一个改进,除非有一个庞大的继承类层次结构,因为这个方法一旦找到定义类就会停止,而不是像getmro
那样返回整个继承.如上所述,这是一个非常不可能的情况.
def get_class_that_defined_method(method):
method_name = method.__name__
if method.__self__:
classes = [method.__self__.__class__]
else:
#unbound method
classes = [method.im_class]
while classes:
c = classes.pop()
if method_name in c.__dict__:
return c
else:
classes = list(c.__bases__) + classes
return None
Run Code Online (Sandbox Code Playgroud)
和例子:
>>> class A(object):
... def test(self): pass
>>> class B(A): pass
>>> class C(B): pass
>>> class D(A):
... def test(self): print 1
>>> class E(D,C): pass
>>> get_class_that_defined_method(A().test)
<class '__main__.A'>
>>> get_class_that_defined_method(A.test)
<class '__main__.A'>
>>> get_class_that_defined_method(B.test)
<class '__main__.A'>
>>> get_class_that_defined_method(C.test)
<class '__main__.A'>
>>> get_class_that_defined_method(D.test)
<class '__main__.D'>
>>> get_class_that_defined_method(E().test)
<class '__main__.D'>
>>> get_class_that_defined_method(E.test)
<class '__main__.D'>
>>> E().test()
1
Run Code Online (Sandbox Code Playgroud)
Alex解决方案返回相同的结果.只要可以使用Alex方法,我就会使用它而不是这个.
我不知道为什么没有人提出这个问题,或者为什么当它慢得要命时,最高答案有 50 个赞成票,但您也可以执行以下操作:
def get_class_that_defined_method(meth):
return meth.im_class.__name__
Run Code Online (Sandbox Code Playgroud)
对于 python 3,我相信这已经改变了,你需要查看.__qualname__
.
在 Python 3 中,如果您需要实际的类对象,您可以执行以下操作:
import sys
f = Foo.my_function
vars(sys.modules[f.__module__])[f.__qualname__.split('.')[0]] # Gets Foo object
Run Code Online (Sandbox Code Playgroud)
如果该函数可能属于嵌套类,则需要按如下方式进行迭代:
f = Foo.Bar.my_function
vals = vars(sys.modules[f.__module__])
for attr in f.__qualname__.split('.')[:-1]:
vals = vals[attr]
# vals is now the class Foo.Bar
Run Code Online (Sandbox Code Playgroud)