2016-01-20 261 views
0

Python和Excel对默认值有不同的行为。 Python是通过关键字传递可选参数,而Excel只是位置,即使在默认情况下。结果,一个未被使用的论证实际上被传递,如无。假设作为例如SciPy的功能brentq:默认情况下python-excel不匹配

brentq(f, a, b, xtol=1e-12, rtol=4.4408920985006262e-16, maxiter=100, full_output=False, disp=True, *args) 

从Excel与xtol调用它,RTOL取消设置:

brentq(f,a,f,,,50) 

会在现实中被视为

brentq(f,a,f,None,None,50) 

当然Python将不像None为xtol,rtol。 作为escamotage,到现在为止,我有一个功能检查的默认值:

def checkvals(f, args): 
    a = inspect.getargspec(f) 
    defs = zip(a.args[-len(a.defaults):], a.defaults) 
    for x in defs: 
     key = x[0] 
     if args[key] == None: 
      args[key] = x[1] 
    return args 

和我换brentq如下:

def brentq(f, a, b, xtol=1e-12, rtol=4.4408920985006262e-16, maxiter=100, full_output=False, disp=True, *args):  
    x = checkvals(brentq, locals()) 
    return scipy.optimize.brentq (f, a, b, *args, x['xtol'], x['rtol'], x['maxiter'], x['full_output'], x['disp']) 

它的工作原理,即X [ 'xtol']和x ['rtol']恢复为默认值。但是,我想知道是否有更好的方法来做到这一点。 换句话说:是否可以修改函数中的locals(),并强制函数使用修改后的值?

+0

这需要更加清晰 - 这是不是一个“巨蟒/ Excel的不匹配,”这是关于Python如何处理默认参数。 –

回答

0

如果Excel在跳过参数时通过None,则将其作为默认参数作为Python函数签名。事实上,这是 Pythonic的方式来做到这一点(由于各种原因,包括不值得进入这里的默认参数可变性)。

brentq(f, a, b, xtol=None, rtol=None, maxiter=100, full_output=None, disp=None, *args): 
    if xtol is None: xtol = 1e-12 
    if rtol is None: rtol = 4.4408920985006262e-16 
    if full_output is None: full_output = False 
    if disp is None: disp = true 
    # ... rest of function 
+0

你是对的,但我试图自动执行excel-python接口:假设必须为所有scipy函数执行手动方法...。 –

+0

@maurizio啊,我错过了这些是SciPy函数。我认为这是使用xlwings? –

+0

不,我正在使用xlloop:一个用作客户端不同服务器的excel .xll,其中包括python。 –

0

我很满意最终凯尔的建议。继它的Excel的Python接口将会像(例如Spyder的尝试):

import scipy.optimize 

def f(x): 
    return -2*x**4 + 2*x**3 + -16*x**2 + -60*x + 100 

#this is the wrapper for Excel 
def brentqWrapper (f, a, b, xtol=None, rtol=None, maxiter=None, full_output=None, disp=None,*args): 
    return scipy.optimize.brentq (**{k: v for k, v in locals().items() if v!=None}) 

#this simulates the excel call with unset inner optional parameters: 
print brentqWrapper(f,0,2,None,None,50) 
>> 1.24078711375