我可能只是错过了一些关于os.environ或copy.deepcopy如何工作的文档,但似乎copy.deepcopy在os.environ上不起作用。但是,如果我将os.environ重建为一个新的字典,它可以正常工作。这是我的示例代码:
import copy
import os
tcsh_loc = '/bin/tcsh'
safe_dict = {}
for key in os.environ.keys():
safe_dict[key] = os.environ[key]
safe_dict['SAFE_ENV'] = 'non-leaked-var'
os.spawnv(os.P_WAIT, tcsh_loc, [tcsh_loc, '-c', 'echo $SAFE_ENV'])
os.spawnve(os.P_WAIT, tcsh_loc, [tcsh_loc, '-c', 'echo $SAFE_ENV'], safe_dict)
unsafe_dict = copy.deepcopy(os.environ)
unsafe_dict['UNSAFE_ENV'] = 'leaked-var'
os.spawnv(os.P_WAIT, tcsh_loc, [tcsh_loc, '-c', 'echo $UNSAFE_ENV'])
os.spawnve(os.P_WAIT, tcsh_loc, [tcsh_loc, '-c', 'echo $UNSAFE_ENV'], unsafe_dict)
我期望得到的是:
SAFE_ENV: Undefined variable.
non-leaked-var
UNSAFE_ENV: Undefined variable.
leaked-var
但我得到的是:
SAFE_ENV: Undefined variable.
non-leaked-var
leaked-var
leaked-var
这意味着某种方式unsafe_dict['UNSAFE_ENV'] = 'leaked-var'
赋值以某种方式“泄漏”到os.environ中,大概来自os.environ没有按照我的预期进行深度复制。
我认为这是某种已知的行为,但对我来说这似乎很奇怪,至少在使用os.spawnev()等方面。我有一个笨拙的解决方法,但我有兴趣了解发生了什么,以及是否有比for循环更优雅的解决方案......
答案 0 :(得分:3)
os.environ
的类型为os._Environ
,而不是列表或字典。合理的是os._Environ
实例的副本也会修改环境。
请参阅os._Environ.__setitem__()
功能。它将值存储在 2个地方中,一次使用putenv()
,另一个用于在self._data
字典中分配密钥。
def __setitem__(self, key, value):
key = self.encodekey(key)
value = self.encodevalue(value)
self.putenv(key, value)
self._data[key] = value
答案 1 :(得分:0)
您可以更轻松地重建它:只需使用dict(os.environ)
。
简单测试:
import os
a=os.environ
b=dict(os.environ)
print type(a), type(b)
# -> <type 'instance'> <type 'dict'>
print a['PWD'], b['PWD']
# -> /home/max /home/max
b['PWD']='/fooo'
print a['PWD'], b['PWD']
# -> /home/max /fooo