在Python中,是否可以在运行时重新定义函数的默认参数?
我在这里定义了一个带3个参数的函数:
def multiplyNumbers(x,y,z):
return x*y*z
print(multiplyNumbers(x=2,y=3,z=3))
Run Code Online (Sandbox Code Playgroud)
接下来,我尝试(不成功)为y设置默认参数值,然后我尝试调用不带参数的函数y
:
multiplyNumbers.y = 2;
print(multiplyNumbers(x=3, z=3))
Run Code Online (Sandbox Code Playgroud)
但是由于y
未正确设置默认值,因此产生了以下错误:
TypeError: multiplyNumbers() missing 1 required positional argument: 'y'
Run Code Online (Sandbox Code Playgroud)
是否有可能在运行时重新定义函数的默认参数,因为我试图在这里做?
Ria*_*iaD 26
multiplyNumbers = functools.partial(multiplyNumbers, y = 42)
Run Code Online (Sandbox Code Playgroud)
这里有一个问题:你将无法调用它,因为multiplyNumbers(5, 7, 9);
你应该手动说y=7
如果您需要删除默认参数,我会看到两种方式:
在某处存储原始功能
oldF = f
f = functools.partial(f, y = 42)
//work with changed f
f = oldF //restore
Run Code Online (Sandbox Code Playgroud)使用 partial.func
f = f.func //go to previous version.
Run Code Online (Sandbox Code Playgroud)从技术上讲,它可以做你所要求的......但这不是一个好主意.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
Run Code Online (Sandbox Code Playgroud)
与其他所有在文档中难以找到的内容一样,inspect
模块图表是查找函数属性的最佳位置.
Python 2中的细节略有不同,但想法是一样的.(只需将文档页面左上角的下拉菜单从3.3更改为2.7.)
如果你想知道Python的知道它默认与论据去的时候,它只是有一个元组...它只是从终端(或第一向后计数*
,*args
,**kwargs
后-anything进入__kwdefaults__
字典代替).f.__defaults = (4, 5)
将设置默认为y
,并z
以4
和5
,并用默认x
.这是有效的,因为在默认参数之后你不能拥有非默认参数.
在某些情况下,这不起作用,但即便如此,您仍可以不可变地将其复制到具有不同默认值的新函数:
>>> f2 = types.FunctionType(f.__code__, f.__globals__, f.__name__,
... (4, 5, 6), f.__closure__)
Run Code Online (Sandbox Code Playgroud)
在这里,types
模块文档并没有真正解释任何内容,但help(types.FunctionType)
在交互式解释器中显示了您需要的参数.
你无法处理的唯一案例是内置函数.但他们通常没有实际的默认值; 相反,他们在C API中伪造了类似的东西.
是的,您可以通过修改函数的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)
Run Code Online (Sandbox Code Playgroud)