all 和 any

allany是内置的归约函数(把某个操作连续应用到序列的元素上,累计之前的结果,把一 系列值归约成一个值)。

  • all(iterable)若可迭代对象中每个元素都是真值,返回True;否则返回False。all([])返回True
  • any(iterable)只要可迭代对象中有元素是真值,返回True;否则返回False。any([])返回False

    判断对象能否调用

    使用内置callable()函数判断对象是否可调用:
    1. lst = [callable(abs), callable(int), callable(13)]
    2. print(lst) # [True, True, False]

    用户定义的可调用类型

    任何Python对象只需实现__call__方法,就可表现得像函数。 ```python import random

class BingoCage:

  1. def __init__(self, items):
  2. self._items = list(items)
  3. random.shuffle(self._items)
  4. def pick(self):
  5. try:
  6. return self._items.pop()
  7. except IndexError:
  8. raise LookupError("Pick from empty BingoCage.")
  9. def __call__(self):
  10. 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对象有namekinddefault属性。

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,)