我需要通过更改名为process.py的应用程序模块头部的默认值来对python模块进行单元测试。声明的默认值是固定的int。我可以改变它来使用os.environ中的其他东西,但我希望简单地指定全局,但显然我错过了对'def'的一些理解。
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
输出应显示例外TimoutExpired。
答案 0 :(得分:1)
在定义时评估函数默认值,而不是调用时间(参见"Least Astonishment" and the Mutable Default Argument)。
访问和修改函数默认值的唯一方法是through its __defaults__
property(旧版本中为func_defaults
):
>>> def f(a=5):
... return a
>>> f.__defaults__
(5,)
>>> f.__defaults__ = (99,)
>>> f()
99
请注意,__defaults__
是一个元组,因此您无法单独指定其成员,但您可以将其分配为一个整体。
答案 1 :(得分: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-:
答案 2 :(得分:0)
关于更改用于测试目的的默认值的原始问题,您可能希望使用作为可变对象的字典。 See my answer there了解详情。