2009-06-07 80 views
52

如何获得在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) 
+0

您使用的是什么版本的Python? 在2.2之前,你可以使用im_class,但是这已经改变,以显示绑定的自我对象的类型。 – 2009-06-07 02:40:18

+1

很高兴知道。但我使用2.6。 – 2009-06-07 02:48:10

回答

54
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 
+0

它的工作原理,谢谢! – 2009-06-07 02:29:24

5

感谢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方法可以使用,我会用它来代替这个。

1

我开始做一些有点类似的事情,基本上这个想法是检查基类中的某个方法是否已经实现或者不在子类中。原来我做这件事的方式,我无法检测到中级班实际上正在实施该方法。

我的解决方法其实很简单;设置方法属性并稍后测试其存在。下面是整个事情的简化:

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:其实叫从run_method()method()(是不是精神?),并把它传递给未修改方法的所有参数。

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

2

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

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

为Python 3我相信这改变了,你需要看看.__qualname__

相关问题