函数的内省:
函数内省(function introspection)
除了__doc__属性, 函数对象还有很多属性,对于下面的函数,可以使用dir()查看函数具有的属性:
1 2 3 4 5 6 7 8 | >>> 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常规类都有的属性,下面重点看看常规对象没有而函数对象有的属性:
1 2 3 4 5 6 7 | >>> 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 函数的限定名称
定位参数和仅限关键字参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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'})>
本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/articles/10423648.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能