如何在python 3中区分实例方法、类方法、静态方法或函数?

How to distinguish an instance method, a class method, a static method or a function in Python 3?

我想区分Python3中的方法和函数。此外,如果它是一个方法,我想得到相应的类。我当前的解决方案如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import types
import inspect

def function_or_method(f):
    if inspect.ismethod(f):
        if inspect.isclass(f.__self__):
            print("class method")
            klass = f.__self__
        else:
            print("instance method")
            klass = f.__self__.__class__
    elif inspect.isfunction(f): # function
        if f.__name__ != f.__qualname__: # to distiguish staticmethod and function
            print("static method")
            # HOW TO GET THE CLASS
        else:
            print("function")
    else:
        print("not function or method")

class Foo():
    def bari(self):
        pass
    @classmethod
    def barc(cls):
        pass
    @staticmethod
    def bars():
        pass

def barf():
    pass

function_or_method(Foo().bari) # instance method
function_or_method(Foo.barc) # class method
function_or_method(Foo.bars) # static method
function_or_method(barf) # function

它能用,但看起来不优雅。我不确定我是否错过了什么。有人知道更好的解决方案吗?

更新1:如果它是一个方法,我还想获取相应的类。我知道如何处理类/实例方法(参见上面的代码),但是如何获得静态方法的类?


您只需要获取方法的类型,但是由于方法是描述符,因此必须:

1-从实例中获取类。2-在__dict__中查找方法引用,而不是进行属性查找。

例如:

1
2
3
4
5
6
7
>>> f = Foo()
>>> type(f.__class__.__dict__['bari'])
<class 'function'>
>>> type(f.__class__.__dict__['barc'])
<class 'classmethod'>
>>> type(f.__class__.__dict__['bars'])
<class 'staticmethod'>

我认为使用inspectisfunction()方法更好。

Syntax:

1
[inspect.getmembers(<module name>, inspect.isfunction)] # will give all the functions in that module

如果要测试单个方法,可以通过…

1
inspect.isfunction(<function name>) # return true if is a function else false

有许多谓词可以与IS函数一起使用。请参阅用于inspect的python 3文档以获得清晰的画面。