python反射之inspect模块

976 阅读2分钟

inspect模块提供了一系列函数用于自省操作。下面进行叙述。

涉及到的类和函数如下:

def test_func(name, age, sex="男", *ids, **info):
    """
    返回个人信息
    :param name: 姓名
    :param age: 年龄
    :param sex: 性别
    :return: 个人信息
    """
    return name + "," + age + "," + sex
​
​
class Person(object):
    """
    这是一个测试类
    """
​
    def __init__(self, name, age):
        self.name = name
        self.age = age
​
    def say(self):
        print(f"{self.name}在谈话")
​
​
p = Person("小明", 23)

1 检查对象类型

1.1 is系列方法

方法说明
ismodule检查对象是否为模块
isclass检查对象是否为类
isfunction检查对象是否为函数
ismethod检查对象是否为方法
isbuiltin检查对象是否为内建函数或方法

eg:

image-20220114111532345.png

import inspect
from test_study import driver_demo
​
print(inspect.ismodule(driver_demo))

result:

True
print(inspect.isfunction(test_func))

result:

True
print(inspect.isclass(Person))
print(inspect.ismethod(p.say))

result:

True
True
print(inspect.isbuiltin(print))

result:

True

1.2 isroutine方法

检查对象是否为函数、方法、内建函数或方法等可调用类型,和is系列的作用完全一致

if inspect.isroutine(p.say):
    p.say()

result:

小明在谈话

1.3 判断对象是否可调用

如果只是判断对象是否可调用,可以采取更简单的判断办法

from collections.abc import Callable


print(isinstance(p.say, Callable))

result:

True

2 获取对象信息

2.1 getmembers方法

该方法是dir()方法的扩展版

print(inspect.getmembers(p.say))

result:

[('__call__', <method-wrapper '__call__' of method object at 0x0000020F307850C8>), ('__class__', <class 'method'>), ('__delattr__', <method-wrapper '__delattr__' of method object at 0x0000020F307850C8>), ('__dir__', <built-in method __dir__ of method object at 0x0000020F307850C8>), ('__doc__', None), ('__eq__', <method-wrapper '__eq__' of method object at 0x0000020F307850C8>), ('__format__', <built-in method __format__ of method object at 0x0000020F307850C8>), ('__func__', <function Person.say at 0x0000020F30E8C048>), ('__ge__', <method-wrapper '__ge__' of method object at 0x0000020F307850C8>), ('__get__', <method-wrapper '__get__' of method object at 0x0000020F307850C8>), ('__getattribute__', <method-wrapper '__getattribute__' of method object at 0x0000020F307850C8>), ('__gt__', <method-wrapper '__gt__' of method object at 0x0000020F307850C8>), ('__hash__', <method-wrapper '__hash__' of method object at 0x0000020F307850C8>), ('__init__', <method-wrapper '__init__' of method object at 0x0000020F307850C8>), ('__init_subclass__', <built-in method __init_subclass__ of type object at 0x00007FFE1190E030>), ('__le__', <method-wrapper '__le__' of method object at 0x0000020F307850C8>), ('__lt__', <method-wrapper '__lt__' of method object at 0x0000020F307850C8>), ('__ne__', <method-wrapper '__ne__' of method object at 0x0000020F307850C8>), ('__new__', <built-in method __new__ of type object at 0x00007FFE1190E030>), ('__reduce__', <built-in method __reduce__ of method object at 0x0000020F307850C8>), ('__reduce_ex__', <built-in method __reduce_ex__ of method object at 0x0000020F307850C8>), ('__repr__', <method-wrapper '__repr__' of method object at 0x0000020F307850C8>), ('__self__', <__main__.Person object at 0x0000020F30E89748>), ('__setattr__', <method-wrapper '__setattr__' of method object at 0x0000020F307850C8>), ('__sizeof__', <built-in method __sizeof__ of method object at 0x0000020F307850C8>), ('__str__', <method-wrapper '__str__' of method object at 0x0000020F307850C8>), ('__subclasshook__', <built-in method __subclasshook__ of type object at 0x00007FFE1190E030>)]

2.2 getmodule方法

类所在模块的模块名,和module方法不同,这里所返回的模块名是一个对象,可以直接调用,而不是字符串形式

print(inspect.getmodule(p.say))

result:

<module '__main__' from 'D:/workspace/test_study/test_study/test.py'>

2.3 getfile方法

获取对象所定义的文件名

print(inspect.getfile(p.say))

result:

D:/workspace/test_study/test_study/test.py

2.4 getsource方法

获取对象的源代码

print(inspect.getsource(p.say))

result:

def say(self):
    print(f"{self.name}在谈话")

2.5 getfullargspec方法

获取方法定义时所声明的参数,其结果是一个元组,分别是(普通参数名列表,*参数名,**参数名,默认值元组)

print(inspect.getfullargspec(test_func))

result:

FullArgSpec(args=['name', 'age', 'sex'], varargs='ids', varkw='info', defaults=('男',), kwonlyargs=[], kwonlydefaults=None, annotations={})

2.6 getargvalues方法

仅用于栈桢,获取栈桢中函数当前调用时的参数值,其结果是一个元组,分别是(普通参数名列表,*参数名,**参数名,栈的locals())

def test_func(name, age, sex="男", *ids, **info, ):
    """
    返回个人信息
    :param name: 姓名
    :param age: 年龄
    :param sex: 性别
    :return: 个人信息
    """
    print(inspect.getargvalues(inspect.currentframe()))
    return name + "," + age + "," + sex

print(test_func("小明", '23'))

result:

ArgInfo(args=['name', 'age', 'sex'], varargs='ids', keywords='info', locals={'name': '小明', 'age': '23', 'sex': '男', 'ids': (), 'info': {}})
小明,23,男

\