Pythonで環境変数を取得・追加・上書き・削除(os.environ)
Pythonのプログラムの中で環境変数を取得して確認したり、設定(追加・上書き)、削除したりするにはos.environ
を使う。なお、環境変数の設定や削除による変更はそのPythonプログラムの中でのみ有効。システムの環境変数が書き換わるわけではない。
osモジュールをインポートして使う。標準ライブラリなので追加のインストールは不要。ここでは環境変数による処理結果の違いを示す例のためにsubprocessモジュールもインポートしている。subprocessモジュールも標準ライブラリに含まれている。
import os
import subprocess
以下の内容について説明する。
os.environ
- 環境変数を取得
- 環境変数を設定(追加・上書き)
- 環境変数を削除
- 環境変数変更の影響
- 環境変数による処理の切り替え
os.environ
os.environ
の型はos._Environ
。
print(type(os.environ))
# <class 'os._Environ'>
os._Environ
はキーkey
と値value
が対になったマップ型オブジェクトで、辞書(dict
型)などと同様のメソッドを持つ。環境変数名がkey
、その値がvalue
になっている。
なお、os.environ
の内容はos
モジュールをインポートした時点で読み込まれる。プログラムの実行中に他の手段でシステムの環境変数が変更されてもos.environ
の内容は更新されない。
print()
で一覧が表示される(ここでは省略)。
# print(os.environ)
辞書と同様にkeys()
やvalues()
などのメソッドを使ったり、in
でキーや値の存在確認をしたりできる。
キー、値の処理も基本的には辞書と同じ。以下に例とともに示す。
環境変数を取得
os.environ[環境変数名]
で環境変数の値を取得できるが、存在しない環境変数名を指定するとエラーKeyError
になる。
print(os.environ['LANG'])
# ja_JP.UTF-8
# print(os.environ['NEW_KEY'])
# KeyError: 'NEW_KEY'
os.environ
のget()
メソッドを使うと、存在しない場合にはデフォルト値を取得できる。辞書と同じ。
print(os.environ.get('LANG'))
# ja_JP.UTF-8
print(os.environ.get('NEW_KEY'))
# None
print(os.environ.get('NEW_KEY', 'default'))
# default
os.getenv()
という関数も用意されている。辞書のget()
メソッドと同様、キーが存在しない場合はデフォルト値を返す。環境変数の値を取得して確認するだけならこの関数が便利。
print(os.getenv('LANG'))
# ja_JP.UTF-8
print(os.getenv('NEW_KEY'))
# None
print(os.getenv('NEW_KEY', 'default'))
# default
環境変数を設定(追加・上書き)
os.environ[環境変数名]
に値を代入すると環境変数を設定できる。
新しい環境変数名を指定するとその環境変数が新たに追加され、既存の環境変数名を指定するとその環境変数の値が上書きされる。
os.environ['NEW_KEY'] = 'test'
print(os.environ['NEW_KEY'])
# test
os.environ['NEW_KEY'] = 'test2'
print(os.environ['NEW_KEY'])
# test2
文字列以外を代入するとエラーTypeError
になるので注意。数値を代入したい場合も文字列として指定する。
# os.environ['NEW_KEY'] = 100
# TypeError: str expected, not int
os.environ['NEW_KEY'] = '100'
os.putenv()
という関数も用意されているが、os.putenv()
で設定した場合はos.environ
の値が更新されないため、上の例のようにos.environ
のキー(環境変数名)を指定して値を代入するほうが望ましい。
putenv() がサポートされている場合、 os.environ のアイテムに対する代入を行うと、自動的に putenv() の対応する呼び出しに変換されます。直接 putenv() を呼び出した場合 os.environ は更新されないため、実際には os.environ のアイテムに代入する方が望ましい操作です。
16.1. os.putenv() — Python 3.6.5 ドキュメント
なお、最初に書いたように、環境変数の追加や上書きによる変更はそのPythonプログラムの中でのみ有効。システムの環境変数が書き換わるわけではない。
OSによっては値の変更がメモリリークの原因となる場合があるので要注意。
注釈 FreeBSD と Mac OS X を含む一部のプラットフォームでは、 environ の値を変更するとメモリリークの原因になる場合があります。
16.1. os.putenv() — Python 3.6.5 ドキュメント
これはOS自体のputenv()
の仕様によるもの。
Successive calls to setenv() or putenv() assigning a differently sized value to the same name will result in a memory leak. The FreeBSD seman-tics semantics for these functions (namely, that the contents of value are copied and that old values remain accessible indefinitely) make this bug unavoidable. Mac OS X Manual Page For putenv(3)
環境変数を削除
環境変数を削除するにはos.environ
のpop()
メソッドやdel
文を使う。辞書と同じ。詳細は以下の記事を参照。
pop()
の例。
pop()
は削除した環境変数の値を返す。デフォルトでは存在しない環境変数を指定するとエラーKeyError
になるが、第二引数を指定すると環境変数が存在しない場合にその値を返す。
print(os.environ.pop('NEW_KEY'))
# 100
# print(os.environ.pop('NEW_KEY'))
# KeyError: 'NEW_KEY'
print(os.environ.pop('NEW_KEY', None))
# None
del
の例。
再度環境変数を追加してから削除している。環境変数が存在しない場合はエラーKeyError
。
os.environ['NEW_KEY'] = '100'
print(os.getenv('NEW_KEY'))
# 100
del os.environ['NEW_KEY']
print(os.getenv('NEW_KEY'))
# None
# del os.environ['NEW_KEY']
# KeyError: 'NEW_KEY'
os.unsetenv()
という関数も用意されているが、os.putenv()
と同様にos.unsetenv()
で削除した場合はos.environ
の値が更新されないため、上の例のようにos.environ
のキー(環境変数名)を指定して削除するほうが望ましい。
unsetenv() がサポートされている場合、 os.environ のアイテムの削除を行うと、自動的に unsetenv() の対応する呼び出しに変換されます。直接 unsetenv() を呼び出した場合 os.environ は更新されないため、実際には os.environ のアイテムを削除する方が望ましい操作です。
16.1. os.unsetenv() — Python 3.6.5 ドキュメント
環境変数の削除についてもそのPythonプログラムの中でのみ有効。システムの環境変数が削除されるわけではない。
環境変数変更の影響
繰り返し書いているようにos.environ
の環境変数を変更(設定・削除)してもシステムの環境変数が変更されるわけではないが、プログラム中で起動されるサブプロセスには影響を与える。
言語設定の環境変数LANG
によって日時を表示するコマンドdate
の結果が変わる例を示す。Windowsでは環境変数LANG
がなくdate
コマンドの内容も違うため以下のコードは期待通りに動作しないので注意。
subprocessモジュールでdate
コマンドを呼び出している。
LANG
の値によってdate
の出力結果が変わる。
print(os.getenv('LANG'))
# ja_JP.UTF-8
print(subprocess.check_output('date', encoding='utf-8'))
# 2018年 7月12日 木曜日 20時54分13秒 JST
#
os.environ['LANG'] = 'en_US'
print(subprocess.check_output('date', encoding='utf-8'))
# Thu Jul 12 20:54:13 JST 2018
#
なお、ここでは説明のためos.environ
で環境変数LANG
を変更しているが、Pythonにはロケールを制御するlocaleモジュールが用意されている。localeモジュールの利用例は以下の記事を参照。
環境変数による処理の切り替え
環境変数の値に応じて処理を切り替えることも可能。
言語設定の環境変数LANG
によって出力を変更する例を示す。ここでは文字列が指定した文字列で始まるかどうかを判定するstartswith()
メソッドを使っているが、完全一致で判定したい場合は==
で比較すればOK。
print(os.getenv('LANG'))
# en_US
if os.getenv('LANG').startswith('ja'):
print('こんにちは')
else:
print('Hello')
# Hello
os.environ['LANG'] = 'ja_JP'
if os.getenv('LANG').startswith('ja'):
print('こんにちは')
else:
print('Hello')
# こんにちは
そのほか、例えば開発環境と本番環境を示す環境変数が設定されている場合などはその値を取得して処理を切り替えたりできる。