os.getenvとos.environ.getの違い


159

両方のアプローチに違いはありますか?

>>> os.getenv('TERM')
'xterm'
>>> os.environ.get('TERM')
'xterm'

>>> os.getenv('FOOBAR', "not found") == "not found"
True
>>> os.environ.get('FOOBAR', "not found") == "not found"
True

それらはまったく同じ機能を持っているようです。

回答:


60

観察された1つの違い(Python27):

os.environ環境変数が存在しない場合は、例外が発生します。 os.getenv例外は発生しませんが、Noneを返します


119
OPは、(特に指定されていない限り)os.environ.get()どちらが返されるかを尋ねNone、envの場合は例外を発生させません。var。存在しません。あなたが混乱していることと、os.environ['TERM']それが問題ではないことを使っていること。
Anthon 2017

2
OPの質問os.environ.get()vs について尋ねますos.getenv()が、本文にはos.environvs も含まれているos.environ.get()ため、この回答は少なくともいくつかの点で正しいです-不完全ですが正しい。
FKEinternet

3
この誤って誤解を招く答えは、否定的な反対票を獲得しているはずです。次の答えは正しい答えです。
RayLuo

80

この関連スレッドを参照してください。基本的にos.environは、インポート時に見つかり、少なくともCPythonではos.getenvへのラッパーos.environ.getです。

編集:CPythonでは、コメントに応答することos.getenvは基本的にへのショートカットos.environ.getです。以降は、os.environ輸入時にロードされos、そしてだけにして、同じことが成り立ちます os.getenv


1
確かに、それは公式のドキュメントによると:docs.python.org/3/library/os.html
ivanleoncz

1
リンクされた関連スレッドから:「os.getenv()[...] を使用する主な理由os.environは、KeyErrorやその他のものがスローされるのではなく、のキーに環境変数名が見つからないときにデフォルト値が返されるようにする場合です。いくつかのキャラクターを保存したい。」
泥棒

35

Python 2.7とiPython:

>>> import os
>>> os.getenv??
Signature: os.getenv(key, default=None)
Source:
def getenv(key, default=None):
    """Get an environment variable, return None if it doesn't exist.
    The optional second argument can specify an alternate default."""
    return environ.get(key, default)
File:      ~/venv/lib/python2.7/os.py
Type:      function

そのos.getenvため、単純なラッパーであると結論付けることができますos.environ.get


16

間には機能的な差がないながらos.environ.getとはos.getenv、ある大規模なos.putenvにエントリを設定し、os.environos.putenv壊れているので、対称性を使用するos.environ.getようにos.getenv促す方法を避けるために、デフォルトに設定する必要がありますos.putenv

os.putenv実際のOSレベルの環境変数を変更しますが、通過表示されない方法でos.getenvos.environまたは環境変数を検査する他のSTDLIB方法:

>>> import os
>>> os.environ['asdf'] = 'fdsa'
>>> os.environ['asdf']
'fdsa'
>>> os.putenv('aaaa', 'bbbb')
>>> os.getenv('aaaa')
>>> os.environ.get('aaaa')

を呼び出したgetenv後に実際の環境変数を確認するには、Cレベルでctypesを呼び出す必要がありますos.putenv。(シェルサブプロセスを起動し、その環境変数を要求することも機能する可能性があります。エスケープおよび--norc/ --noprofile/スタートアップ構成を回避するために必要なその他のことについて非常に注意している場合は、正しく行うのがはるかに難しいようです。)


2

上記の回答に加えて:

$ python3 -m timeit -s 'import os' 'os.environ.get("TERM_PROGRAM")'
200000 loops, best of 5: 1.65 usec per loop

$ python3 -m timeit -s 'import os' 'os.getenv("TERM_PROGRAM")'
200000 loops, best of 5: 1.83 usec per loop

テストしたPythonのバージョン。3.7.2では、はのos.getenvラッパーにすぎないためos.environ.get、オーバーヘッドは最小限に抑えられます。
Preslav Rachev

macOS Mojaveでは3.7.1でした。タイミングはかなり一貫していた。
fredrik、

@PreslavRachevは最小限であるかどうかにかかわらず、追加の関数呼び出しであるため、オーバーヘッドが発生します。そうは言っても、おそらく内部ループの途中でenv変数を取得する必要はありません。
pmav99

7
まったく関係ありません。単一の関数呼び出しのマイクロ最適化...どのアプリケーションでも、とにかくブートストラップでのみ環境を読み取る必要があるため、これはさらに重要ではありません。
VictorSchröder19年

1
ところで、usecマイクロ秒ですtimeit。このマイクロベンチマークで見つかった差は0.18マイクロ秒でした...
VictorSchröder19年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.