函数内省(function introspection)
除了__doc__属性, 函数对象还有很多属性,对于下面的函数,可以使用dir()查看函数具有的属性:
1
|
>>> 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
|
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) |
1
2
3
4
5
6
7
8
9
10
|
<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
|
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模块把实参绑定给函数调用:
1
2
3
4
5
|
(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' })> |
到此这篇关于python 函数定位参数+关键字参数+inspect模块的文章就介绍到这了,更多相关python inspect模块内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.51cto.com/u_12903656/5290389