• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
孙龙 程序员
少时总觉为人易,华年方知立业难
博客园    首页    新随笔    联系   管理    订阅  订阅
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'})>

 

本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/articles/10423648.html

posted on 2019-02-23 18:10  孙龙-程序员  阅读(191)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3