python 函数定位参数+关键字参数+inspect模块
时间:2022-11-19 10:51:36|栏目:Python代码|点击: 次
函数内省(function introspection)
除了__doc__属性, 函数对象还有很多属性,对于下面的函数,可以使用dir()查看函数具有的属性:
>>> dir(factorial) ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
其中大多数是Python常规类都有的属性,下面重点看看常规对象没有而函数对象有的属性:
>>> class C:pass ... >>> obj = C() >>> def func():pass ... >>> sorted(set(dir(func)) - set(dir(obj))) # 计算差集,然后排序 ['__annotations__', '__call__', '__closure__', '__code__', '__defaults__', '__get__', '__globals__', '__kwdefaults__', '__name__', '__qualname__']
对于上面列出的函数特有属性,说明如下:
- __annotations__ dict 参数和返回值的注释
- __call__ method-wrapper 实现()运算符,即可调用对象的协议
- __closure__ tuple 函数闭包,即自由变量的绑定(通常是None)
- __code__ code 编译成字节码的函数元数据和函数定义体
- __defaults__ tuple 形式参数的默认值
- __get__ method-wrapper 实现只读描述符协议
- __globals__ dict 函数所在的模块中的全局变量
- __kwdefaults__ dict 仅限关键字形式参数的默认值
- __name__ str 函数名称
- __qualname__ str 函数的限定名称
定位参数和仅限关键字参数
def tag(name,*content,cls=None,**attrs): if cls is not None: attrs['class'] = cls if attrs: attrs_str = ''.join(' %s="%s" ' % (attr,value) for attr,value in sorted(attrs.items())) else: attrs_str='' if content: return '\n'.join('<%s %s >%s</%s>' % (name,attrs_str,c,name) for c in content) else: return '<%s%s />' % (name,attrs_str) print(tag('br'))#定位参数 name print(tag('p','hello'))#hello 会被*conteng捕获 存入元组content = ('hello') print(tag('p','hello','world'))#content = ('hello','world') print(tag('p','hello',id=33)) #attrs={'id':33} content = ('hello') print(tag('p','hello','world',cls='sidebar'))#cls 关键字传入 cls='sidebar' print(tag(content='testing',name='img'))#第一个参数name 也能作为关键字传入 #同名键会绑定到对应的具名参数上,剩余的则会被**attrs捕获 print(tag(**{'name':'img','title':'sunset boulevard','src':'sunset.jpg','cls':'framed'})) #仅限关键字参数是python3.0新增的特性,在上例中,cls参数只能通过关键字参数指定,他一定不会捕获未命名的定位参数 #定义函数时候,如果想指定仅限关键字参数,要把它们放到*的参数后面 def f(a,*,b): return a,b ff = f(1,b=2) print(ff)
<br /> <p >hello</p> <p >hello</p> <p >world</p> <p id="33" >hello</p> <p class="sidebar" >hello</p> <p class="sidebar" >world</p> <img content="testing" /> <img class="framed" src="sunset.jpg" title="sunset boulevard" /> (1, 2)
inspect模板
def tag(name,*content,cls=None,**attrs): if cls is not None: attrs['class'] = cls if attrs: attrs_str = ''.join(' %s="%s" ' % (attr,value) for attr,value in sorted(attrs.items())) else: attrs_str='' if content: return '\n'.join('<%s %s >%s</%s>' % (name,attrs_str,c,name) for c in content) else: return '<%s%s />' % (name,attrs_str) import inspect sig = inspect.signature(tag) print(sig) my_tag = {'name':'img','title':'sun long','src':'sunlong.jpg','cls':'framed'} bound_args = sig.bind(**my_tag) for name,value in bound_args.arguments.items(): print(name,'=',value) print(bound_args)
inspect模块把实参绑定给函数调用:
(name, *content, cls=None, **attrs) name = img cls = framed attrs = {'title': 'sun long', 'src': 'sunlong.jpg'} <BoundArguments (name='img', cls='framed', attrs={'title': 'sun long', 'src': 'sunlong.jpg'})>