当我看着optimize.minimize
的代码,我发现它将任务传递给像_minimize_neldermead
这样的函数。反过来,这些拨打电话,如:
fcalls, func = wrap_function(func, args)
<more setup>
... = func(x0)
... = func(y)
这是(从scipy/optimize/optimize.py
):
def wrap_function(function, args):
ncalls = [0]
if function is None:
return ncalls, None
def function_wrapper(*wrapper_args):
ncalls[0] += 1
return function(*(wrapper_args + args))
return ncalls, function_wrapper
所以args
由它们串联到变量(wrapper_args
),将通过元组的函数处理。这是一个简单,直接的包装机制。
此.py
文件学分
# optimize.py module by Travis E. Oliphant
...
# A collection of optimization algorithms. Version 0.5
# CHANGES
# Added fminbound (July 2001)
特拉维斯头是一个非常重要的numpy
原开发商。注意早年的变化。我假设这个包装是在scipy安装在github存储库之前很久才添加的,但是你肯定可以检查。
描述包装功能如何解释他为什么选择它。这可能是因为他在FORTRAN和C包之后对API进行了建模。其中一些scipy
优化,ode和插值函数最终使用编译代码。
我发现改变了这种包装函数的语法2013拉请求:
- def function_wrapper(x):
+ def function_wrapper(*wrapper_args):
ncalls[0] += 1
- return function(x, *args)
+ return function(*(wrapper_args + args))
https://github.com/scipy/scipy/commit/cf3adca80e371fd19a34b398d2f1ed0e19f0cbdc
https://github.com/scipy/scipy/issues/3785
显然有些人有问题,定义args
作为列表或单个项目,而不是元组。有SO问题,人们使用args=(x)
而不是args=(x,)
。在issue
中提到的替代方案是functools.partial
。
这几乎是一个更广泛的语言设计问题。 – zxq9