获取定义了方法的类

122 投票
13 回答
88334 浏览
提问于 2025-04-15 12:05

我想知道在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)

13 个回答

8

感谢Sr2222指出我之前的理解有误...

这里是修正后的方法,跟Alex的方法差不多,但不需要导入任何东西。不过我觉得这并不是一个改进,除非有很多层级的继承类,因为这个方法一旦找到定义的类就会停止,而不是像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

还有一个例子:

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

Alex的解决方案返回的结果是一样的。只要可以使用Alex的方法,我会选择用它,而不是这个。

13

我不知道为什么没人提过这个问题,或者为什么最受欢迎的回答有50个赞,但它的速度慢得要命。不过,你也可以这样做:

def get_class_that_defined_method(meth):
    return meth.im_class.__name__

对于Python 3,我觉得这个情况有变化,你需要看看 .__qualname__

80

当然可以!请看下面的内容:

在编程中,有时候我们需要让程序做一些重复的事情,比如计算、处理数据或者显示信息。为了让这些事情更简单,我们可以使用“循环”。循环就像是一个指令,让程序不停地重复执行某些操作,直到满足特定的条件。

想象一下,你在做一个简单的任务,比如数数。如果你要从1数到10,你可以一个一个地数,但如果用循环的话,你只需要告诉程序“从1开始,数到10,每次加1”,这样程序就会自动帮你完成这个任务。

循环有几种不同的类型,比如“for循环”和“while循环”。“for循环”通常用来处理已知次数的重复,而“while循环”则是在你不确定要重复多少次时使用,直到某个条件不再满足。

总之,循环是编程中一个非常重要的工具,能让我们更高效地完成任务,避免重复写很多相似的代码。

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

撰写回答