我有一个功能:
def dummy_func(a, b: float, c: int = 1) -> float:
#some code
我想编写一个通用函子(dummy_prepender
),该函子将使用该函数并构造一个新的函子,它与原始函子的唯一区别是在签名之前附加了一个未使用的参数:
dummy_method1 = dummy_prepender(dummy_func)
#dummy_method1 should behave exactly like the following code:
def dummy_method(dummy, a, b: float, c: int = 1) -> float:
#some code
因此对于任何一组参数和dummy_arg
dummy_method(dummy_arg, arguments...)
的行为与dummy_func(arguments...)
完全相同。
我认为@staticmethod
可以解决问题,但是在某些地方,调度的执行方式有所不同,并且应用静态方法无效。
一些行为测试:
help(dummy_method)
应该显示正确的签名
dummy_method(dummy='', a=1)
应该失败
dummy_method(dummy='', a=1, b=2, c=3, z=4)
应该失败
更新:
以下是staticmethod
无法正常工作的示例:
示例1
factory_type = type('Typ1', (), {
'__init__': staticmethod(dummy_func),
})
inspect.signature(factory_type)
#<Signature (b:float, c:int=1) -> float>
#BTW, in this case it's just the inspect.signature that is broken. The call behavior seems to be correct
示例2:
factory_type2 = type('Typ1', (), {
'__new__': staticmethod(dummy_func),
})
#Call behavior is broken
factory_type2(a=1, b=2)
# TypeError: dummy_func() got multiple values for argument 'a'
factory_type2(7, 13)
# locals()={'c': 13, 'b': 7, 'a': <class '__main__.Typ1'>}
# See how the class got passed as `a` instead of `dummy`
staticmethod(func)
的结果不是函数,而是描述符对象。有时行为是不一样的。
答案 0 :(得分:0)
我的第一次尝试是这样的:
def dummy_method(*args, **kwargs) -> float:
return dummy_func(*args[1:], **kwargs)
即将推出的Python 3.8实现了PEP 570,该语法允许以下语法:
# 'dummy' is a positional only argument, disallowing 'dummy=...'
def dummy_method(dummy, /, *args, **kwargs) -> float:
return dummy_func(*args, **kwargs)
这里是Python 3.8的另一个版本,保留了签名:
def dummy_method(dummy, /, a, b: float, c: int = 1) -> float:
return dummy_func(a, b, c)