【发布时间】:2021-11-13 00:13:59
【问题描述】:
我创建了一个方法create_function,它根据参数返回另一个具有修改行为的函数。我的实现工作正常,但有一件事困扰着我:返回的函数有这个名称<function create_function.<locals>.new_func at ...>。这使得错误消息难以解释,因为在不同的函数上使用 create_function 会导致它们在引发异常时具有几乎相同的名称。
create_function
def create_function(func, arguments: dict):
def new_func(x):
return func(x, **arguments)
return new_func
f = create_function(sum, {})
f() # Missing the parameter x should raise exception.
> TypeError: new_func() missing 1 required positional argument: 'x'
我尝试使用装饰器,但效果不佳。
def rename(new_name):
def decorator(f):
f.__name__ = new_name
return f
return decorator
def create_function(func, arguments: dict):
@rename("Test")
def new_func(x):
return func(x, **arguments)
return new_func
f = create_function(sum, {})
print(f.__name__)
f()
> Test
> TypeError: new_func() missing 1 required positional argument: 'x'
那么有没有办法将返回函数的名称更改为 new_func 以外的其他名称?
编辑
所以为了更清楚一点,我想在引发错误时显示输入函数的名称(在上面的示例中:sum 而不是new_func)。
按照 Jiri Baum 的建议,使用 functools 中的 wraps 可以更接近目标:
使用包装
from functools import wraps
def create_function(func, arguments: dict):
@wraps(func)
def new_func(x):
return func(x, **arguments)
return new_func
f = create_function(sum, {})
print(f.__name__) # Printing the name of the returned function
f() # Raising an Type Error on purpose to show the Exception message
> <function sum at .> # This is what I wanted to show up!
> TypeError: new_func() missing 1 required positional argument: 'x'
# No, here comes new_func again...
那么有什么办法可以让异常说类似
TypeError: sum() missing 1 required positional argument???
编辑 2: 有人可以帮我吗?
【问题讨论】:
-
使用来自
contextlib的wraps装饰器? -
对于
rename装饰器,您不需要额外的级别... -
@JiříBaum 你能详细说明一下吗?我在 contextlib 中找不到
wraps decorator。如果没有额外的关卡,你会如何改变当前的装饰器? -
对不起,
wrapsfromfunctools: docs.python.org/3/library/functools.html#functools.wraps -
对于额外的级别,我想我看错了你的代码;他们的水平很好。缺少的参数是“x” - 我不确定你想要
x是什么,但是当你调用f()时你没有提供它
标签: python function types functional-programming python-decorators