函数内省
函数有很多种属性,而其中的很多种属性也是普通对象所有的。使用dir
命令可查看函数的所有属性
>>> def foo():
... pass
...
>>> dir(foo)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>>
再定义一个普通对象,查看他有哪些属性:
>>> class A:
... pass
...
>>> a = A()
>>> dir(a)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>>
>>> sorted(set(dir(foo)) - set(dir(a))) # 函数有但普通对象没有的属性
['__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 | 函数的限定名称,如 Random.choice |
偏函数
functools.partial这个高阶函数用于部分应用一个函数,部分应用是指,基于一个函数创建一个新的可调用对象,把原函数的某些参数固定。使用这个函数可以把
接受一个或多个参数的函数改编成需要的回调API,这样减少参数的使用。基本形式如下:
functools.partial(func[,*args][, **kwargs])
>>> from operator import mul
>>> from functools import partial
>>> triple = partial(mul, 3)
>>> triple(7)
21
>>> list(map(triple, range(1, 10))) [3, 6, 9, 12, 15, 18, 21, 24, 27]
partial的第一个参数是一个可调用对象,后面跟着要绑定的定位参数和关键字参数,在调用新函数时,实际上会把的第一个参数传入到可调用对象。
总结:当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。