为了测试查询环境的事物(例如os.getenv
,sys.version
等),通常更方便的方法是让查询内容失效,而不是实际伪造环境。这里有一个上下文管理器,可以一次为一个os.getenv
调用执行此操作:
from __future__ import with_statement
from contextlib import contextmanager
import os
@contextmanager
def fake_env(**fakes):
'''fakes is a dict mapping variables to their values. In the
fake_env context, os.getenv calls try to return out of the fakes
dict whenever possible before querying the actual environment.
'''
global os
original = os.getenv
def dummy(var):
try: return fakes[var]
except KeyError: return original(var)
os.getenv = dummy
yield
os.getenv = original
if __name__ == '__main__':
print os.getenv('HOME')
with fake_env(HOME='here'):
print os.getenv('HOME')
print os.getenv('HOME')
但这仅适用于os.getenv
,如果允许具有多个参数的函数,则语法会变得有些笨拙。我想在ast
和code
/exec
/eval
之间,我可以将要覆盖的函数作为参数扩展它,但不够简洁。此外,我将走上格林斯潘第十条路。有更好的方法吗?
'os.getenv'
)中提取模块和名称。谢谢! - Wanglocals()
/globals()
中查找它,那么当模块以不同的名称导入(例如import csv as bob
)时,它就会出错。 - Wangoriginal.__module__
不会受到as
子句的影响——试试看! - Alex Martellioriginal.__module__
总是使用标准名称,而sys.modules
总是将标准名称映射到模块。但是locals()
/globals()
可能会在as
子句名称下列出它。 - Wang