Учитывая все, что сказали респонденты и комментаторы, вот что я получил.
Точный w sh синтаксически невозможен, но есть два способа достижения искомой простоты.
Просто используйте inspect.signature
в качестве декоратора:
>>> from inspect import signature
>>> @signature
... def sig1(a, b: int, c=0, d: float=0.0): ...
>>> @signature
... def sig2(something_else): ...
>>> @signature
... def sig3(): ...
>>>
>>> sig1
<Signature (a, b: int, c=0, d: float = 0.0)>
>>> sig2
<Signature (something_else)>
>>> sig3
<Signature ()>
Но если вам нужно что-то более динамичное c, я предлагаю следующее:
def sig(obj: Union[Signature, Callable, Mapping, None] = None, return_annotations=_empty, **annotations):
"""Convenience function to make a signature or inject annotations to an existing one.
"""
if obj is None:
return Signature()
if callable(obj):
obj = Signature.from_callable(obj) # get a signature object from a callable
if isinstance(obj, Signature):
obj = obj.parameters # get the parameters attribute from a signature
params = dict(obj) # get a writable copy of parameters
if not annotations:
return Signature(params.values(), return_annotation=return_annotations)
else:
assert set(annotations) <= set(params), \
f"These argument names weren't found in the signature: {set(annotations) - set(params)}"
for name, annotation in annotations.items():
p = params[name]
params[name] = Parameter(name=name, kind=p.kind, default=p.default, annotation=annotation)
return Signature(params.values(), return_annotation=return_annotations)
Демо:
>>> s = sig(lambda a, b, c=1, d='bar': ..., b=int, d=str)
>>> s
<Signature (a, b: int, c=1, d: str = 'bar')>
>>> # showing that sig can take a signature input, and overwrite an existing annotation:
>>> sig(s, a=list, b=float) # note the b=float
<Signature (a: list, b: float, c=1, d: str = 'bar')>
>>> sig()
<Signature ()>
>>> sig(lambda a, b=2, c=3: ..., d=int) # trying to annotate an argument that doesn't exist
Traceback (most recent call last):
...
AssertionError: These argument names weren't found in the signature: {'d'}