我怎样才能获得该在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)
有帮助吗?

解决方案

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

其他提示

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

亚历溶液返回相同的结果。只要亚历方法可以用于,我会用它来代替这一个。

我不知道为什么从来没有人提出这为什么顶端回答有50个upvotes当它是缓慢的地狱,但你也可以做到以下几点:

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

对于Python 3,我相信这个改变,你需要寻找到.__qualname__

我开始有些类似,基本想法是,只要检查在基类中的方法已经在子类中实现与否。原来我原先所采取的方式,当一个中间类实际上实现该方法我无法检测。

我为它的解决方法是相当简单实际上;设定的方法的属性并以后测试它的存在。下面是整个事情的简化:

class A():
    def method(self):
        pass
    method._orig = None # This attribute will be gone once the method is implemented

    def run_method(self, *args, **kwargs):
        if hasattr(self.method, '_orig'):
            raise Exception('method not implemented')
        self.method(*args, **kwargs)

class B(A):
    pass

class C(B):
    def method(self):
        pass

class D(C):
    pass

B().run_method() # ==> Raises Exception: method not implemented
C().run_method() # OK
D().run_method() # OK

UPDATE:其实从method()调用run_method()(?不是精神),并具有将它传递到未改性方法的所有参数

P.S:此答案不直接回答这个问题。恕我直言,有两个原因一个想知道哪一个类中定义的方法;第一是在调试代码的类(例如,在异常处理)以指向手指,第二个是,以确定是否该方法已被重新实现(其中的方法是意在由编程实现的存根)。此答案解决了不同的方式,第二壳体。

在Python 3中,如果需要的实际类对象可以这样做:

import sys
f = Foo.my_function
vars(sys.modules[f.__module__])[f.__qualname__.split('.')[0]]  # Gets Foo object

如果该功能可能属于一个嵌套类,你会需要遍历如下:

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top