Python 3.3+inspectпонятие
inspect.BoundArguments
сигнатуры
Результат Signature.bind(): какие значения достались каким параметрам. Через args и kwargs по нему можно вызвать функцию.
Синтаксис
ba = sig.bind(*args, **kwargs); ba.apply_defaults(); func(*ba.args, **ba.kwargs)
В arguments попадают только явно переданные значения: умолчаний там нет, пока не вызван apply_defaults(). Главная польза — достать аргумент по имени, как бы его ни передали, позиционно или ключом: так пишут декораторы-проверки. arguments — обычный изменяемый dict, и правка в нём сразу меняет args и kwargs.
Примеры
import inspect
def connect(host, port=5432, *, timeout=10):
return f'{host}:{port} t={timeout}'
ba = inspect.signature(connect).bind('db', timeout=3)
print(ba.arguments) # → {'host': 'db', 'timeout': 3}
ba.apply_defaults()
print(ba.arguments) # → {'host': 'db', 'port': 5432, 'timeout': 3}
print(connect(*ba.args, **ba.kwargs)) # → db:5432 t=3
import functools, inspect
def positive(name):
def deco(fn):
sig = inspect.signature(fn)
@functools.wraps(fn)
def wrapper(*args, **kwargs):
ba = sig.bind(*args, **kwargs)
ba.apply_defaults()
if ba.arguments[name] <= 0:
raise ValueError(f'{name} must be > 0')
return fn(*args, **kwargs)
return wrapper
return deco
@positive('n')
def repeat(s, n=1):
return s * n
print(repeat('ab', 2), repeat('x', n=3)) # → abab xxx
try:
repeat('a', 0)
except ValueError as e:
print(e) # → n must be > 0
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности