是否可以更改函数';Python中的默认参数是什么?
在Python中,是否可以在运行时重新定义函数的默认参数 我在这里定义了一个具有3个参数的函数:是否可以更改函数';Python中的默认参数是什么?,python,function,Python,Function,在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的默认值,因此产生了
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'
是否可以像我在这里尝试的那样,在运行时重新定义函数的默认参数?只需使用
这里有一个问题:您将无法将其称为multilynumbers(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.
使用中的
func\u默认值
def myfun(a=3):
return a
myfun.func_defaults = (4,)
b = myfun()
assert b == 4
检查文档中的函数默认值
更新:看着里亚德的回答,我觉得我的回答太直截了当了。我不知道你问这个问题的背景,但总的来说(以及接下来的问题),我相信使用部分应用程序比重新定义函数的默认参数更好。从技术上讲,可以按你的要求做……但这不是一个好主意。里亚德的答案是用蟒蛇的方式来做这件事
在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
与文档中难以找到的其他内容一样,模块图是查找函数属性的最佳位置
Python2中的细节略有不同,但思想是相同的。(只需将文档页面左上角的下拉列表从3.3更改为2.7。)
如果您想知道Python如何知道当它刚得到一个元组时哪些默认值与哪些参数一起…它只是从末尾向后计数(或者从*
,*args
,**kwargs
——之后的任何内容都会进入\kwdefaults\uuu
dict)<代码>f.uu默认值=(4,5)
将默认值设置为y
和z
为4
和5
,默认值设置为x
。这是因为在默认参数之后不能有非默认参数
在某些情况下,这将不起作用,但即使如此,您也可以使用不同的默认值将其永久复制到新函数:
>>> f2 = types.FunctionType(f.__code__, f.__globals__, f.__name__,
... (4, 5, 6), f.__closure__)
在这里,文档并没有真正解释任何内容,但是交互式解释器中的help(types.FunctionType)
显示了您需要的参数
唯一不能处理的情况是内置函数。但它们通常没有实际违约;相反,它们在C API中伪造了类似的东西。在函数上设置属性
y
,也不会更改y
@joshlf13的默认参数,您可能也使用静态语言。您的意思是可以做类似于代码片段的事情吗?我想有一个足够强大的类型系统是可能的,但我不知道很多这样的语言。我想有很多函数式语言,但我指的是命令式语言(尽管我应该明确地说)。实际上,想想看,这基本上就像咖喱,只是不需要对变量进行排序。@AndersonGreen,我确实理解。我的意思是,我不知道如何直接做,但你可以按照下面的oldF=f;f=部分(…);f=oldF
@AndersonGreen,添加了一些信息,但我没有将其设置为3个变量中的第二个。“仅适用于我的最后一个。@RiaD:函数默认值必须是参数的最终序列;正如您不能编写def foo(x,y=2,z):
,您也不能将func\u默认值
/默认值
更改为只覆盖y
。您提到在运行时更改函数的默认参数“不是一个好主意”。你注意到这种方法有什么缺点吗?(我还没有意识到任何问题)。@AndersonGreen:有一个明显的缺点,那就是它使您、其他人、linter、IDE、基于反射的工具(如pickle
)更难理解您的代码。而且,您必须完全了解有关args/params的规则,以确保操作正确。还有一个事实是,如果不编写能够处理常规函数、奇怪的不可变函数(需要从代码中构造新函数)和内置函数(需要用部分
或调用它的新函数包装)的代码,就无法使其正常工作.我们可以从lambda
函数内部执行类似于f.\uuuuu默认值(4,5,6)
的操作吗@abarnert@DiptangsuGoswamilambda
不允许赋值,尽管3.8中的赋值表达式在技术上可以实现。
>>> f2 = types.FunctionType(f.__code__, f.__globals__, f.__name__,
... (4, 5, 6), f.__closure__)