获取已定义方法的类

如何获得在 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)
73141 次浏览
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

Alex 解决方案返回相同的结果。只要亚历克斯的方法可以使用,我会使用它,而不是这一个。

我开始做一些类似的事情,基本上就是检查基类中的方法是否在子类中实现。事实证明,我最初的方法无法检测到中间类实际实现该方法的时间。

我的解决方案实际上非常简单: 设置一个方法 属性,然后测试它的存在性。以下是整个事情的简化:

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

更新: 实际上从 run_method()调用 method()(这难道不是精神吗?)并让它将所有未修改的参数传递给方法。

附注: 这个答案并不直接回答这个问题。恕我直言,人们想知道哪个类定义了一个方法有两个原因: 第一个原因是在调试代码中对一个类指指点点(例如在异常处理中) ,第二个原因是确定该方法是否已经被重新实现(其中方法是程序员应该实现的存根)。这个答案以一种不同的方式解决了第二种情况。

我不知道为什么从来没有人提起过这个问题,也不知道为什么排名最靠前的答案有50个赞同票,而它却慢得要命,但是你也可以这样做:

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

对于 python3,我相信这已经改变了,您需要查看 .__qualname__

在 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

巨蟒3

用一种非常简单的方法解决了这个问题:

str(bar.foo_method).split(" ", 3)[-2]

这给

'FooClass.foo_method'

在点上拆分以分别获得类和函数名

我发现 _ _ qualname _ _在 Python 3中很有用。

我是这样测试的:

class Cls(object):
def func(self):
print('1')


c = Cls()
print(c.func.__qualname__)
# output is: 'Cls.func'
def single_func():
print(2)


print(single_func.__module__)
# output: '__main__'
print(single_func.__qualname__)
# output: 'single_func'

经过我的测试,我找到了另一个答案 给你