Get class that defined method
如何获取在Python中定义方法的类?
我希望下面的示例打印"
1 2 3 4 5 6 7 8 9 | class FooClass: def foo_method(self): print"foo" class BarClass(FooClass): pass bar = BarClass() print get_class_that_defined_method(bar.foo_method) |
1 2 3 4 5 6 7 | 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指出我错过了要点…
这是正确的方法,和亚历克斯的方法一样,但不需要导入任何内容。不过,我不认为这是一种改进,除非在找到定义类后,继承类的层次结构非常庞大,因为这种方法会立即停止,而不是像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | >>> 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解决方案返回相同的结果。只要亚历克斯的方法可以使用,我会使用它而不是这个。
我不知道为什么没有人提出过这个问题,也不知道为什么当速度慢得像地狱一样时,最上面的答案有50个赞成票,但是你也可以做以下的事情:
1 2 | def get_class_that_defined_method(meth): return meth.im_class.__name__ |
对于python 3,我相信这已经改变了,您需要研究
我开始做一些类似的事情,基本上,只要基类中的一个方法已经实现或者不在子类中,这个想法就是检查。原来我是这样做的,当一个中间类实际实现该方法时,我无法检测到。
实际上,我对它的解决方法相当简单:设置一个方法属性并稍后测试它的存在。以下是整个过程的简化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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 |
更新:实际上从
附言:这个答案不能直接回答问题。imho有两个原因,一个是想知道哪个类定义了一个方法;第一个是指调试代码中的一个类(例如在异常处理中),第二个是确定该方法是否被重新实现(其中,方法是一个由程序员实现的存根)。这个答案以不同的方式解决了第二个问题。
在Python3中,如果需要实际的类对象,可以执行以下操作:
1 2 3 | import sys f = Foo.my_function vars(sys.modules[f.__module__])[f.__qualname__.split('.')[0]] # Gets Foo object |
如果函数可以属于嵌套类,则需要按如下方式迭代:
1 2 3 4 5 | f = Foo.Bar.my_function vals = vars(sys.modules[f.__module__]) for attr in f.__qualname__.split('.'): vals = vals[attr] # vals is now the class Foo.Bar |