python - Python装饰函数保留部分签名
问题描述
我写了以下装饰器:
def partializable(fn):
def arg_partializer(*fixable_parameters):
def partialized_fn(dynamic_arg):
return fn(dynamic_arg, *fixable_parameters)
return partialized_fn
return arg_partializer
这个装饰器的目的是将函数调用分成两个调用。如果我装饰以下内容:
@partializable
def my_fn(dyn, fix1, fix2):
return dyn + fix1 + fix2
然后我可以这样做:
core_accepting_dynamic_argument = my_fn(my_fix_1, my_fix_2)
final_result = core_accepting_dynamic_argument(my_dyn)
我的问题是现在装饰my_fn
的显示以下签名:my_fn(*fixable_parameters)
我希望它是:my_fn(fix1, fix2)
我怎样才能做到这一点?我可能必须使用wraps
ordecorator
模块,但我只需要保留原始签名的一部分,我不知道这是否可能。
解决方案
从https://stackoverflow.com/a/33112180/9204395获得灵感,可以通过手动更改 的签名来完成此操作arg_partializer
,因为在相关范围内只有 的签名fn
是已知的并且可以使用inspect
.
from inspect import signature
def partializable(fn):
def arg_partializer(*fixable_parameters):
def partialized_fn(dynamic_arg):
return fn(dynamic_arg, *fixable_parameters)
return partialized_fn
# Override signature
sig = signature(fn)
sig = sig.replace(parameters=tuple(sig.parameters.values())[1:])
arg_partializer.__signature__ = sig
return arg_partializer
这不是特别优雅,但当我想到这个问题时,我开始怀疑这(或概念上的等价物)是实现这一特技的唯一可能方法。随意反驳我。
推荐阅读
- fabricjs - 将元素保持在悬停结构 js 的覆盖层之上
- javascript - socket.io - 仅在客户端上未定义套接字
- android - 如何在运行时由android应用程序执行可执行文件
- html - 如何将内容置于位置:绝对?
- r - 如何将秒转换为R中的日期
- c# - 如何读取/写入超过 2 GB 大小障碍的文件?
- c# - 如何通过 codefirst 迁移更快地在控制器中手动生成数据库表?
- android - 当我单击手机的后退按钮时,“无法将 java.lang.String 类型的对象转换为类型”
- c# - WPF WebView 不显示任何内容
- laravel - hasMany 关系返回未定义的属性