4

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ループよりもエレガントなソリューションがあるかどうかを理解したいと思います...

4

2 に答える 2

3

os.environはタイプos._Environであり、リストや辞書ではありません。os._Environのインスタンスのコピーが環境も変更することは論理的です。

関数を参照してくださいos._Environ.__setitem__()値を2つの場所に保存します。1つは辞書putenv()にキーを割り当てるために使用します。self._data

def __setitem__(self, key, value):
    key = self.encodekey(key)
    value = self.encodevalue(value)
    self.putenv(key, value)
    self._data[key] = value
于 2012-10-30T16:04:53.157 に答える
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
于 2014-09-27T12:00:07.980 に答える