python 函数定位参数+关键字参数+inspect模块

目录

函数内省(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\'})>
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容