在Python中,是否可以在运行时重新定义函数的默认参数?
我在这里定义了一个带有3个参数的函数:
def multiplyNumbers(x,y,z):
return x*y*z
print(multiplyNumbers(x=2,y=3,z=3))
接下来,我尝试(不成功)为y设置默认参数值,然后我尝试调用不带参数y
的函数:
multiplyNumbers.y = 2;
print(multiplyNumbers(x=3, z=3))
但由于未正确设置y
的默认值,因此产生了以下错误:
TypeError: multiplyNumbers() missing 1 required positional argument: 'y'
是否有可能在运行时重新定义函数的默认参数,因为我试图在这里做?
答案 0 :(得分:24)
multiplyNumbers = functools.partial(multiplyNumbers, y = 42)
此处存在一个问题:您无法将其称为multiplyNumbers(5, 7, 9);
,您应手动说出y=7
如果您需要删除默认参数,我会看到两种方式:
将原始功能存储在某处
oldF = f
f = functools.partial(f, y = 42)
//work with changed f
f = oldF //restore
使用partial.func
f = f.func //go to previous version.
答案 1 :(得分:7)
从技术上讲,你可以做你所要求的......但这不是一个好主意。 RiaD的答案是Pythonic的方法。
在Python 3中:
>>> def f(x=1, y=2, z=3):
... print(x, y, z)
>>> f()
1 2 3
>>> f.__defaults__ = (4, 5, 6)
4 5 6
与文档中难以找到的其他内容一样,inspect
模块图表是查找函数属性的最佳位置。
Python 2中的细节略有不同,但想法是一样的。 (只需将文档页面左上角的下拉菜单从3.3更改为2.7。)
如果你想知道Python如何知道哪些默认值与哪些参数一起得到一个元组...它只是从末尾开始向后计数(或*
的第一个,*args
,{{ 1}} - 之后的任何内容都会转移到**kwargs
dict中。 __kwdefaults__
会将默认设置为f.__defaults = (4, 5)
,将y
设置为z
和4
,默认设置为5
。这是有效的,因为在默认参数之后你不能有非默认参数。
在某些情况下,这不起作用,但即便如此,您仍可以不可避免地将其复制到具有不同默认值的新功能:
x
在这里,types
module文档并没有真正解释任何内容,但是交互式解释器中的>>> f2 = types.FunctionType(f.__code__, f.__globals__, f.__name__,
... (4, 5, 6), f.__closure__)
显示了您需要的参数。
无法处理的唯一情况是内置函数。但他们通常没有实际的默认值;相反,他们在C API中伪造了类似的东西。
答案 2 :(得分:0)
在
中使用func_defaults
def myfun(a=3):
return a
myfun.func_defaults = (4,)
b = myfun()
assert b == 4
查看func_defaults here
的文档更新:关注RiaD的反应我觉得我的文字过于粗俗。我不知道你问这个问题的上下文,但总的来说(和Zen of Python之后)我认为使用部分应用程序是比重新定义函数的默认参数更好的选择
答案 3 :(得分:0)
是的,您可以通过修改函数的 func.__defaults__
元组来实现这一点
该属性是函数每个参数的默认值的元组。
例如,要使 pandas.read_csv
始终使用 sep='\t'
,您可以这样做:
import inspect
import pandas as pd
default_args = inspect.getfullargspec(pd.read_csv).args
default_arg_values = list(pd.read_csv.__defaults__)
default_arg_values[default_args.index("sep")] = '\t'
pd.read_csv.__defaults__ = tuple(default_arg_values)