[351]python的inspect模块

inspect模块主要提供了四种用处

1、对是否是模块,框架,函数等进行类型检查。

2、获取源码

3、获取类或函数的参数的信息

4、解析堆栈

# -*-coding:UTF-8 -*-
import inspect

def a(a, b=0, *c, d, e=1, **f):
    pass

aa = inspect.signature(a)
print("inspect.signature(fn)是:%s" % aa)
print("inspect.signature(fn)的类型:%s" % (type(aa)))
print("\n")

bb = aa.parameters
print("signature.paramerters属性是:%s" % bb)
print("ignature.paramerters属性的类型是%s" % type(bb))
print("\n")

for cc, dd in bb.items():
    print("mappingproxy.items()返回的两个值分别是:%s和%s" % (cc, dd))
    print("mappingproxy.items()返回的两个值的类型分别是:%s和%s" % (type(cc), type(dd)))
    print("\n")
    ee = dd.kind
    print("Parameter.kind属性是:%s" % ee)
    print("Parameter.kind属性的类型是:%s" % type(ee))
    print("\n")
    gg = dd.default
    print("Parameter.default的值是: %s" % gg)
    print("Parameter.default的属性是: %s" % type(gg))
    print("\n")


ff = inspect.Parameter.KEYWORD_ONLY
print("inspect.Parameter.KEYWORD_ONLY的值是:%s" % ff)
print("inspect.Parameter.KEYWORD_ONLY的类型是:%s" % type(ff))

运行结果:

inspect.signature(fn)是:(a, b=0, *c, d, e=1, **f)
inspect.signature(fn)的类型:<class 'inspect.Signature'>


signature.paramerters属性是:OrderedDict([('a', <Parameter "a">), ('b', <Parameter "b=0">), ('c', <Parameter "*c">), ('d', <Parameter "d">), ('e', <Parameter "e=1">), ('f', <Parameter "**f">)])
ignature.paramerters属性的类型是<class 'mappingproxy'>


mappingproxy.items()返回的两个值分别是:a和a
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>


Parameter.kind属性是:POSITIONAL_OR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>


Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>


mappingproxy.items()返回的两个值分别是:b和b=0
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>


Parameter.kind属性是:POSITIONAL_OR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>


Parameter.default的值是: 0
Parameter.default的属性是: <class 'int'>


mappingproxy.items()返回的两个值分别是:c和*c
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>


Parameter.kind属性是:VAR_POSITIONAL
Parameter.kind属性的类型是:<enum '_ParameterKind'>


Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>


mappingproxy.items()返回的两个值分别是:d和d
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>


Parameter.kind属性是:KEYWORD_ONLY
Parameter.kind属性的类型是:<enum '_ParameterKind'>


Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>


mappingproxy.items()返回的两个值分别是:e和e=1
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>


Parameter.kind属性是:KEYWORD_ONLY
Parameter.kind属性的类型是:<enum '_ParameterKind'>


Parameter.default的值是: 1
Parameter.default的属性是: <class 'int'>


mappingproxy.items()返回的两个值分别是:f和**f
mappingproxy.items()返回的两个值的类型分别是:<class 'str'>和<class 'inspect.Parameter'>


Parameter.kind属性是:VAR_KEYWORD
Parameter.kind属性的类型是:<enum '_ParameterKind'>


Parameter.default的值是: <class 'inspect._empty'>
Parameter.default的属性是: <class 'type'>


inspect.Parameter.KEYWORD_ONLY的值是:KEYWORD_ONLY
inspect.Parameter.KEYWORD_ONLY的类型是:<enum '_ParameterKind'>

小结

inspect.signature(fn)将返回一个inspect.Signature类型的对象,值为fn这个函数的所有参数

inspect.Signature对象的paramerters属性是一个mappingproxy(映射)类型的对象,值为一个有序字典(Orderdict)。

这个字典里的key是即为参数名,str类型

这个字典里的value是一个inspect.Parameter类型的对象,根据我的理解,这个对象里包含的一个参数的各种信息

inspect.Parameter对象的kind属性是一个_ParameterKind枚举类型的对象,值为这个参数的类型(可变参数,关键词参数,etc)

inspect.Parameter对象的default属性:如果这个参数有默认值,即返回这个默认值,如果没有,返回一个inspect._empty类。

inspect模块类

inspect.ArgInfo               inspect.getmoduleinfo

inspect.ArgSpec               inspect.getmodulename

inspect.Arguments             inspect.getmro

inspect.Attribute             inspect.getouterframes

inspect.BlockFinder           inspect.getsource

inspect.CO_GENERATOR          inspect.getsourcefile

inspect.CO_NESTED             inspect.getsourcelines

inspect.CO_NEWLOCALS          inspect.imp

inspect.CO_NOFREE             inspect.indentsize

inspect.CO_OPTIMIZED          inspect.isabstract

inspect.CO_VARARGS            inspect.isbuiltin

inspect.CO_VARKEYWORDS        inspect.isclass

inspect.EndOfBlock            inspect.iscode

inspect.ModuleInfo            inspect.isdatadescriptor

inspect.TPFLAGS_IS_ABSTRACT   inspect.isframe

inspect.Traceback             inspect.isfunction

inspect.attrgetter            inspect.isgenerator

inspect.classify_class_attrs  inspect.isgeneratorfunction

inspect.cleandoc              inspect.isgetsetdescriptor

inspect.currentframe          inspect.ismemberdescriptor

inspect.dis                   inspect.ismethod

inspect.findsource            inspect.ismethoddescriptor

inspect.formatargspec         inspect.ismodule

inspect.formatargvalues       inspect.isroutine

inspect.getabsfile            inspect.istraceback

inspect.getargs               inspect.joinseq

inspect.getargspec            inspect.linecache

inspect.getargvalues          inspect.modulesbyfile

inspect.getblock              inspect.namedtuple

inspect.getcallargs           inspect.os

inspect.getclasstree          inspect.re

inspect.getcomments           inspect.stack

inspect.getdoc                inspect.string

inspect.getfile               inspect.strseq

inspect.getframeinfo          inspect.sys

inspect.getinnerframes        inspect.tokenize

inspect.getlineno             inspect.trace

inspect.getmembers            inspect.types

inspect.getmodule             inspect.walktree

其中,isxxx之类的就是检查对象是否为xxx的函数吧

例如 检查this是否是一个模块

In [16]: inspect.ismodule(this)
Out[16]: True

getxxx之类的就是获取对象的xxx属性,例如

In [17]:  inspect.getmodule(this)
Out[17]: <module 'this' from '/usr/lib/python2.7/this.pyc'>
  • 实例
# 判断模块、框架、类、函数的方法,和type返回的类型是一样的,只是这里是判断
inspect.getmodulename(path)   获取模块名称
inspect.ismodule(object)      是不是个模块
inspect.isclass(object)       是不是个类
inspect.ismethod(object)      是不是一个方法
inspect.isfunction(object)    是不是一个函数
inspect.isgeneratorfunction(object)   是不是一个生成器函数
inspect.isgenerator(object)           是不是一个生成器
inspect.iscoroutinefunction(object)   是不是一个协程函数
inspect.getsource(object)             获取对象的源码(并不会解析装饰器原码)
inspect.getsourcelines(object)        代码块,每行一个元素,组成数组

# signature 类 函数的签名信息:它包含了了函数的函数名、它的参数类型,它所在的类和名称空间及其他信息
# signature.parameters 里面存放的是函数的参数注解和返回值注解,组成的有序字典
# 参数注解常用的方法有:
empty        等同于inspect._empty表示一个参数没有被类型注释
name         参数的名称
default      参数的默认值,如果一个参数没有默认值,这个属性的值为inspect.empty
annotation   参数的注解类型,如果参数没有定义注解,这个属性的值为inspect.empty
kind         参数的类型
# 参数类型
_POSITIONAL_ONLY         = _ParameterKind.POSITIONAL_ONLY       # 位置参数_only
_POSITIONAL_OR_KEYWORD   = _ParameterKind.POSITIONAL_OR_KEYWORD # 位置或关键字参数
_VAR_POSITIONAL          = _ParameterKind.VAR_POSITIONAL        # 可变位置参数
_KEYWORD_ONLY            = _ParameterKind.KEYWORD_ONLY          # keyword-only参数
_VAR_KEYWORD             = _ParameterKind.VAR_KEYWORD           # 可变关键字参数
# 获取对象的参数签名
>>> import inspect
>>> def add(x:int,y:int):
...     return x+y

>>> sig = inspect.signature(add)
>>> params = sig.parameters
>>> print(params)
OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">)])
>>> params['x'].annotation
<class 'int'>  # 如果没有定义x的参数注解,那么这里就是inspect._empty

# 案例检查参数

import inspect
import functools

def check(fn):  # 这个装饰器只能用于函数,不能用于类方法
    @functools.wraps(fn)
    def warpper(*args, **kwargs):
        sig = inspect.signature(fn)  # 获取fn的参数
        params = sig.parameters  # 有序字典,OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">)])
        values = list(params.values())
        for i,j in enumerate(args):
            if values[i].annotation != inspect._empty and not isinstance(j, values[i].annotation):
                raise TypeError("you must input {}".format(values[i].annotation))
        for k,v in kwargs.items():
            if params[k].annotation != inspect._empty and not not isinstance(v,params[k].annotation):
                raise TypeError("you must input {}".format(params[k].annotation))
        return fn(*args, **kwargs)
    return warpper

@check
def add(x:int,y:int):
    return x+y

print(add(1,2))

# --------------------------获取函数的名字-------------------------------
def debug():
    import inspect
    caller_name = inspect.stack()[1][3]
    print("[DEBUG]: enter {}()".format(caller_name))
def say_hello():
    debug()
    print("hello!")

say_hello()

# 结果:
[DEBUG]: enter say_hello()
hello!

获取对象信息

  • getmembers(object[, predicate]):
    这个方法是dir()的扩展版,它会将dir()找到的名字对应的属性一并返回,形如[(name, value), …]。另外,predicate是一个方法的引用,如果指定,则应当接受value作为参数并返回一个布尔值,如果为False,相应的属性将不会返回。使用is*作为第二个参数可以过滤出指定类型的属性。
  • getmodule(object):
    还在为第2节中的__module__属性只返回字符串而遗憾吗?这个方法一定可以满足你,它返回object的定义所在的模块对象。
  • get{file|sourcefile}(object):
    获取object的定义所在的模块的文件名|源代码文件名(如果没有则返回None)。用于内建的对象(内建模块、类、函数、方法)上时会抛出TypeError异常。
  • get{source|sourcelines}(object):
    获取object的定义的源代码,以字符串|字符串列表返回。代码无法访问时会抛出IOError异常。只能用于module/class/function/method/code/frame/traceack对象。
  • getargspec(func):
    仅用于方法,获取方法声明的参数,返回元组,分别是(普通参数名的列表, *参数名, **参数名, 默认值元组)。如果没有值,将是空列表和3个None。如果是2.6以上版本,将返回一个命名元组(Named Tuple),即除了索引外还可以使用属性名访问元组中的元素。
  • getargvalues(frame):
    仅用于栈帧,获取栈帧中保存的该次函数调用的参数值,返回元组,分别是(普通参数名的列表, *参数名, **参数名, 帧的locals())。如果是2.6以上版本,将返回一个命名元组(Named Tuple),即除了索引外还可以使用属性名访问元组中的元素。
  • getcallargs(func[, *args][, **kwds]):
    返回使用args和kwds调用该方法时各参数对应的值的字典。这个方法仅在2.7版本中才有。
  • getmro(cls):
    返回一个类型元组,查找类属性时按照这个元组中的顺序。如果是新式类,与cls.__mro__结果一样。但旧式类没有__mro__这个属性,直接使用这个属性会报异常,所以这个方法还是有它的价值的。 返回当前的栈帧对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周小董

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值