获取定义方法的类

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)

  • 我得到:`'function'对象没有属性'im_class' (21认同)
  • 对于`Python 3`,请参阅[此答案](http://stackoverflow.com/a/25959545/3903832). (14认同)
  • 对于那些只使用 python 3 的人来说——使用 `meth.__qualname__` 有什么问题吗? (5认同)
  • 请注意,并非所有类都实现“__dict__”!有时会使用“__slots__”。最好使用“getattr”来测试该方法是否在类中。 (4认同)
  • 在Python 2.7中它不起作用.关于缺少'im_class'的相同错误. (4认同)

est*_*ani 7

感谢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方法,我就会使用它而不是这个.


Nic*_*man 7

我不知道为什么没有人提出这个问题,或者为什么当它慢得要命时,最高答案有 50 个赞成票,但您也可以执行以下操作:

def get_class_that_defined_method(meth):
    return meth.im_class.__name__
Run Code Online (Sandbox Code Playgroud)

对于 python 3,我相信这已经改变了,你需要查看.__qualname__.

  • 唔。当我在 python 2.7 中这样做时,我没有看到定义类——我得到的是调用该方法的类,而不是定义它的类... (2认同)

Mat*_*eld 6

在 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)