python——inspect模块

inspect模块常用功能

import inspect  # 导入inspect模块
inspect.isfunction(fn)   # 检测fn是不是函数
inspect.isgenerator((x for x in range(10)))  # 检测是否是生成器
inspect.isclass(int)   # 检测int是不是类
inspect.isbuiltin(print)  # 检测print是不是内建函数(built-in function)
import random
inspect.ismodule  # 检测random是不是模块

我们把其中的inspect . signature(function)拿出来单独分析,如下:

def add(x:int, y:int):  # 定义一个函数
	return x + y
import inspect
sig = inspect.signature(add)  # 获取一个函数的参数签名
print(sig)    # (x: int, y: int)
parms = sig.parameters
print(parms)  # 打印一个有序字典,字典的key是add函数的形参,字典的values是函数的形参key对应的各种属性,我们学习一下它的annotation属性
# OrderedDict([('x', <Parameter "x: int">), ('y', <Parameter "y: int">)])
print(parms['x'].annotation)  # <class 'int'> 形参x的注释类型是int

应用——业务实战

通过上面的分析,我们学到了如何获得一个函数的注释信息,现在我们要实现一个业务:
函数参数类型检查,即在传参调用的时候自动检查传入的实际参数和形参的注释进行对比,如果不同,给出提示。

思路:- 函数参数的检查,最好在函数外,可以想到使用装饰器
- __annotation__属性是一个字典

import inspect
from functools import wraps
def logger(fn):
    d = {}
    @wraps(fn)
    def wrapper(*args, **kwargs):
        print(kwargs)
        sig = inspect.signature(fn)
        params = sig.parameters
        print(params)
        for i,v in enumerate(params.values()):
            d[f'{i}'] = v.annotation
        for i,x in enumerate(args):
            if d[f'{i}'] == 'inspect._empty' or type(x) == d[f'{i}']:
                print(x, '很ok,没问题')
            else:
                print(x, '类型不对')
        for k,v in kwargs.items():
            if type(v) == params[k].annotation:
                print(v,'ok,可以')
            else:
                print(v,'不行')
        ret = fn(*args, **kwargs)
       # print(d)
        # print(d['1'])
        return ret
    return wrapper
@logger
def add(x:str, y:int=7)->int:
    return x + y
add(3,y='sdf')
posted @ 2019-08-23 09:38  段明  阅读(2244)  评论(0编辑  收藏  举报