关于python:如何在没有实例的情况下检查方法?

How to inspect a method without instance?

本问题已经有最佳答案,请猛点这里访问。

我需要:

  • 将方法作为参数接收(直接从类接收,不带实例)
  • 创建实例
  • 从实例执行所述方法

问题是,如何可靠地将类从方法中去掉?我试过在inspect模块中进行研究,但由于没有实例,它认为该方法是function而不是method的方法。

下面是我要做的一些例子:

1
2
3
4
5
6
7
8
9
10
11
def execute_method(method):
    cls = get_class_from_method(method)
    obj = cls()
    getattr(obj, method.__name__)()


def get_class_from_method(method):
    pass # how?


execute_method(HelloView.say_hello)

python 2方法对象具有引用其绑定到的实例的类的im_class属性:

1
cls = method.im_class

对于未绑定的方法,在python 3中,您将走运(返回的函数完全不变,没有对类的引用)。python 2返回一个未绑定的方法类型,其中im_class属性仍然存在:

1
2
3
4
5
>>> class Foo(object):
...     def bar(self): pass
...
>>> Foo.bar.im_class
<class '__main__.Foo'>

在Python3中,您的选项非常有限,而且容易出错。您可以查看函数的__qualname__属性,并从中推断类在全局命名空间中可能绑定到的内容:

1
2
3
4
5
6
7
8
9
10
11
>>> class Foo:
...     def bar(self): pass
...
>>> Foo.bar
<function Foo.bar at 0x10e97b268>
>>> Foo.bar.__qualname__
'Foo.bar'
>>> Foo.bar.__qualname__.rpartition('.')[0]
'Foo'
>>> Foo.bar.__globals__.get(Foo.bar.__qualname__.rpartition('.')[0])
<class '__main__.Foo'>

但是,如果类是在一个函数中创建的(因此是本地的),或者类是通过类修饰器替换的,或者只是在全局命名空间中重命名的,那么上面的技巧充其量是行不通的,最坏的情况是给你一个完全不同的对象,而你不知道这是不是真的。