2013-10-31 23 views
2

我需要通過更改名爲process.py的應用程序模塊頭中的默認值來單元測試python模塊。聲明的默認值是一個固定的int。我可以改變它來使用os.environ中的其他東西,但我希望簡單地分配全局,但顯然我缺少對'def'的一些理解。python模塊變量不能作爲函數默認

process.default_timeout_secs = 2 

# --name: process 

default_timeout_secs = 120 

def call_process(cmd, timeout=default_timeout_secs): 
    print 'run:', cmd, 'timeout:', timeout 
    ... 



# --name: test_process 
from nose.tools import * 
import process 

@ raises(TimeoutExpired) 
def test_process_run_modified_default(): 
    process.default_timeout_secs = 5 
    run(sleep 10) 

我從其他的帖子明白,對於default_timeout_secs的process.call_process.func_defaults值不是一個在模塊的頂部時,該模塊是進口的。我如何更改函數中使用的默認值?

process.default_timeout_secs = 5個 process.call_process.func_globals [ 'DEFAULT_TIMEOUT'] process.call_process.func_defaults (120)

Out[21]: 5 
>>> process.call_process(cmd) 

Out[22]: call_process: cmd= sleep 2 timeout= 120  <----- 120? 
     Executing cmd sleep 2 verbose=True 

輸出應該顯示異常TimoutExpire d。

回答

1

功能默認值是在定義時間評估的,而不是呼叫時間(請參閱"Least Astonishment" and the Mutable Default Argument)。

訪問和修改功能默認是through its __defaults__ propertyfunc_defaults在舊版本)的唯一方法:

>>> def f(a=5): 
...  return a 
>>> f.__defaults__ 
(5,) 
>>> f.__defaults__ = (99,) 
>>> f() 
99 

注意__defaults__是一個元組,所以你不能將它的成員單獨分配,但可以將其指定爲整個。

0
d = list(process.call_process.func_defaults) 

In [10]: d 
Out[10]: [True, True, 120] 

In [11]: d[-1] = 5 

In [12]: d 
Out[12]: [True, True, 5] 

In [13]: t = tuple(d) 

In [14]: t 
Out[14]: (True, True, 5) 

In [15]: process.call_process.func_defaults = t 
process.call_process('sleep 8') 

call_process(cmd, verbose, shell, timeout, **kwargs) 
    94   except: 
    95    print(str(c.getName()) + 'running cmd "'+ cmd+ '" could not be terminated') 
---> 96   raise TimeoutExpired('calling '+cmd) 
    97  else: 
    98   return c.response 

TimeoutExpired: calling sleep 8 

In [17]: call_process result: 0 :--:-None-: 
0

關於您的原始問題更改默認爲測試目的,您可能想要使用一個可變對象的字典。 See my answer there瞭解詳情。