目录
函数内省(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
暂无评论内容