all 和 any
all和any是内置的归约函数(把某个操作连续应用到序列的元素上,累计之前的结果,把一 系列值归约成一个值)。
all(iterable)若可迭代对象中每个元素都是真值,返回True;否则返回False。all([])返回Trueany(iterable)只要可迭代对象中有元素是真值,返回True;否则返回False。any([])返回False判断对象能否调用
使用内置callable()函数判断对象是否可调用:lst = [callable(abs), callable(int), callable(13)]print(lst) # [True, True, False]
用户定义的可调用类型
任何Python对象只需实现__call__方法,就可表现得像函数。 ```python import random
class BingoCage:
def __init__(self, items):self._items = list(items)random.shuffle(self._items)def pick(self):try:return self._items.pop()except IndexError:raise LookupError("Pick from empty BingoCage.")def __call__(self):return self.pick()
bingo = BingoCage(range(3)) print(bingo()) # 返回0、1、2任意数
<a name="N54A1"></a>
### 获取函数信息
| **名称** | **类型** | **说明** |
| --- | --- | --- |
| `__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` |
```python
def add(a: int, b=1, *, c=2):
'''
计算和
:param a: int 加数1
:param b: int 加数2
:param c: int 加数3
:return: int 和
'''
return a + b + c
print(f"add.__defaults__: {add.__defaults__}") # (1,)
print(f"add.__kwdefaults__: {add.__kwdefaults__}") # {'c': 2}
print(f"add.__name__: {add.__name__}") # add
inspect 提取和绑定函数签名
inspect模块可提取函数签名。inspect.signature返回一个inspect.Signature对象,它有一个parametres属性,这是一个有序映射,将参数名和inspect.Parameter对象对应起来。各个Parameter对象有name、kind、default属性。
from inspect import signature
def clip(text, max_len=80):
pass
sig = signature(clip)
print(str(sig)) # (text, max_len=80)
for name, param in sig.parameters.items():
print(f"{param.kind} : {name} = {param.default}")
# 1 : text = <class 'inspect._empty'> 注:1对应POSITIONAL_OR_KEYWORD(定位参数或关键字参数)
# 1: max_len = 80
inspect.Signature对象的bind方法,可以将任意实参绑定到签名的形参上。框架可以使用这个方法在真正调用函数前验证参数。
from inspect import signature
def tag(name: str, *content, cls=None, **attrs):
# ...
pass
sig = signature(tag)
params = {"name": "img", "title": "Sunset", "src": "Sunset.jpg", "cls": "framed"}
# 绑定实参
bound_args = sig.bind(**params)
for name, value in bound_args.arguments.items():
print(f"{name} = {value}")
# name = img
# cls = framed
# attrs = {'title': 'Sunset', 'src': 'Sunset.jpg'}
# 删除name参数绑定则报错
del params["name"]
sig.bind(**params) # TypeError: missing a required argument: 'name'
函数注解
函数注解存储在__annotations__属性(字典)中:
def clip(text: str, max_len: 'int > 0' = 80) -> str:
pass
print(clip.__annotations__) # {'text': <class 'str'>, 'max_len': 'int > 0', 'return': <class 'str'>}
print(clip.__defaults__) # (80,)
