Python os.environとは?環境変数を辞書のように扱う方法

Pythonのos.environは、環境変数を辞書のように読み書きできるオブジェクトです。

APIキーやデータベースのパスワードなど、コードに書きたくない設定を外から渡すために使います。


os.environの基本的な使い方

import os

print(os.environ["PATH"])

実行結果(例):

/usr/local/bin:/usr/bin:/bin

辞書と同じようにキーで値を取り出せます。

import os

print(type(os.environ))
print(len(os.environ))

実行結果(例):

<class 'os._Environ'>
61

正確には辞書そのものではなく、辞書のように振る舞う専用のオブジェクトです。書き換えると実際の環境変数にも反映されます。


存在しないキーはKeyError

import os

print(os.environ["NO_SUCH_VAR"])

実行結果:

KeyError: 'NO_SUCH_VAR'

これは辞書と同じ挙動です。環境変数は設定されていないことが普通なので、そのまま[]で読むのは危険です。

安全な読み方

import os

print(os.environ.get("NO_SUCH_VAR"))
print(os.environ.get("NO_SUCH_VAR", "デフォルト値"))
print(os.getenv("NO_SUCH_VAR", "デフォルト値"))

実行結果:

None
デフォルト値
デフォルト値

os.environ.get()とos.getenv()はまったく同じ動作です。詳しくは「Python os.getenv()とは?環境変数を安全に取得する方法」をご覧ください。

必須の設定は明示的に落とす

import os

try:
    api_key = os.environ["API_KEY"]
except KeyError:
    raise SystemExit("環境変数 API_KEY が設定されていません")

なければ動かせない設定は、デフォルト値でごまかさず[]で読んで落とすほうが安全です。設定漏れに起動時点で気づけます。


値は必ず文字列

import os

os.environ["PORT"] = "8080"

print(os.environ["PORT"])
print(type(os.environ["PORT"]))

実行結果:

8080
<class 'str'>

数値を代入しようとするとエラーになります。

import os

os.environ["PORT"] = 8080

実行結果:

TypeError: str expected, not int

読み取るときも常に文字列なので、数値として使うなら変換が必要です。

import os

port = int(os.environ.get("PORT", "8000"))
print(port + 1)

実行結果:

8001

真偽値の落とし穴

import os

os.environ["DEBUG"] = "False"

# NG: 空でない文字列はすべてTrue
if os.environ["DEBUG"]:
    print("デバッグモード(意図と逆)")

# OK
if os.environ["DEBUG"].lower() in ("1", "true", "yes"):
    print("デバッグモード")
else:
    print("通常モード")

実行結果:

デバッグモード(意図と逆)
通常モード

文字列の"False"は真です。空でない文字列はすべてTrueと評価されるため、必ず中身を比較してください。


設定してもPython終了後には残らない

import os

os.environ["MY_VAR"] = "hello"
print(os.environ["MY_VAR"])

この変更が有効なのは実行中のPythonプロセスの中だけです。スクリプトが終われば消えます。ターミナルの環境変数は変わりません。

ただし子プロセスには引き継がれます。

import os
import subprocess

os.environ["MY_VAR"] = "hello"
subprocess.run(["python3", "-c", "import os; print(os.environ['MY_VAR'])"])

実行結果:

hello

外部コマンドに設定を渡したいときに使えます。ただし全体を書き換えたくない場合は、subprocessのenv引数を使うほうが安全です。

import os
import subprocess

env = os.environ.copy()
env["MY_VAR"] = "hello"

subprocess.run(["python3", "-c", "import os; print(os.environ['MY_VAR'])"], env=env)

copy()で辞書のコピーを作れば、自分のプロセスの環境変数は汚さずに済みます。


一覧を確認する

import os

for key in sorted(os.environ):
    if key.startswith("PY"):
        print(f"{key} = {os.environ[key]}")

実行結果(例):

PYTHONPATH = /Users/user/lib

デバッグ時に便利ですが、環境変数を丸ごとログに出すのは避けてください。APIキーやパスワードが含まれている可能性があります。


.envファイルで管理する

開発中は.envファイルに書いておき、ライブラリで読み込む方法が一般的です。

API_KEY=abcdef123456
DEBUG=true
from dotenv import load_dotenv
import os

load_dotenv()
print(os.environ.get("API_KEY"))
pip install python-dotenv

.envは必ず.gitignoreに入れてください。誤ってコミットすると、APIキーが公開リポジトリに残り続けます。


詳しくは「Python configparserとは?設定ファイルを読み書きする方法」で解説しています。

Windowsでは大文字小文字を区別しない

import os

print(os.environ.get("path"))
print(os.environ.get("PATH"))

Windowsではどちらでも同じ値が返ります。macOS / Linuxでは区別されるため、pathでは取得できません。

環境変数名は大文字で統一するのが、OSを問わず安全な書き方です。


os.environのまとめ

  • os.environは環境変数を辞書のように扱えるオブジェクト
  • 存在しないキーはKeyError。通常は.get()かos.getenv()を使う
  • 必須の設定はあえて[]で読んで落とすのも有効
  • 値は必ず文字列。数値はint()、真偽値は中身を比較する
  • 設定はPython終了で消えるが、子プロセスには引き継がれる
  • 環境変数をログに出さない。.envは.gitignoreへ
  • 変数名は大文字で統一する

あわせて読みたい


configparser の解説

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら