※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。


【Python3】環境変数を利用するオブジェクトos.environについて解説

python3 設定 environ os python 環境変数

投稿日:2020年11月5日

このエントリーをはてなブックマークに追加
os.environは環境変数を取得できるPythonのビルトインのオブジェクトです。このオブジェクトは非常に便利なのですが、動作が少しだけ複雑です。この記事では実際のコードを交えつつ、このos.environについて詳しく解説しています。

基本

os.environはOSの環境変数を表すマップ型オブジェクトです。

環境変数の読み込みを簡単に行えます。

import os

env = os.environ
print(env["SHELL"])
出力
/bin/bash

値の取得方法

os.environからの値の取得はブレース([ ])でのキー指定とget()メソッドを使う方法とで2種類あるのですが、

この2つは指定したキーの値が存在しなかった場合の動作に違いがあるためキチンと使い分けましょう。

値が存在する場合

値が存在する場合の動作については、どちらも違いはありません。

import os

print(os.environ["SHELL"])
print(os.environ.get("SHELL"))
出力
/bin/bash
/bin/bash

存在しないキーを指定した場合

ブレース([ ])で存在しないキーを指定した場合

import os 

print(os.environ["AAAAAA"])
出力
KeyError                                  Traceback (most recent call last)
<ipython-input-12-4037482a6e5f> in <module>
----> 1 print(env["AAAAAA"])

/usr/lib/python3.8/os.py in __getitem__(self, key)
    673         except KeyError:
    674             # raise KeyError with the original key value
--> 675             raise KeyError(key) from None
    676         return self.decodevalue(value)
    677 

KeyError: 'AAAAAA'

エラーが投げられます。

get()メソッドは第2引数にキーが存在しなかった場合のデフォルト値を指定できます。

import os

print(os.environ.get("AAAAA","No Value"))
出力
No Value

使い分け

使い分けとしては

  • ブレース([ ]):指定した環境変数が存在しないことがアプリケーションにとって異常な事態であり、プログラムの途中終了、ログへの出力、管理者への通知などを行いたい場合
  • get():指定したキーの環境変数の値が頻繁に入れ替わるなどして、存在しないこともありえる場合

のように考えると良いでしょう。


値のセット

基本

os.environはdict型の様に扱えるため、キーを指定し値を変更することができます。

import os

env = os.environ
print("before : {}".format(env["SHELL"]))
env["SHELL"] = "/bin/sh"
print("after : {}".format(env["SHELL"]))
出力
before : /bin/bash
after : /bin/sh

値が存在しない場合のみセット

setdefault()関数を使うと、値が存在しない場合のみ値を入れることもできます。

import os

# 値が存在しない場合にはセット
print("before : {}".format(os.environ.get("AAAAA","NO_VALUE")))
os.environ.setdefault("AAAAA","/bin/sh")
print("after : {}".format(os.environ.get("AAAAA","NO_VALUE")))

# 値がある場合にはスルー
print("before : {}".format(os.environ.get("SHELL","NO_VALUE")))
os.environ.setdefault("SHELL","/bin/sh")
print("after : {}".format(os.environ.get("SHELL","NO_VALUE")))

環境変数への影響

環境変数をマッピングしたコレクションの値を変えて何の意味があるの?

と思う方もいるかもしれません。

実はos.environの値を変更した場合、環境変数自体が更新されるのです。

値の変更・削除などをして確認してみましょう。

import os

env = os.environ
os.system("echo SHELL=$SHELL")
env["SHELL"] = "/bin/sh"
os.system("echo SHELL=$SHELL")
env.pop("SHELL")
os.system("echo SHELL=$SHELL")
出力
SHELL=/bin/bash
SHELL=/bin/sh
SHELL=

このようにos.environの値をかえると環境変数自体が変更されていることがわかります。


クラスについて

_Environクラス

os.environos._Environというクラスであり、dict型とは少し違います。

import os
print(type(os.environ))
出力
<class 'os._Environ'>

os._Environクラスはcollections.abc.MutableMappingを継承したMapping型になっています。

print(type(os.environ).mro())
出力
[<class 'os._Environ'>,
 <class 'collections.abc.MutableMapping'>,
 <class 'collections.abc.Mapping'>,
 <class 'collections.abc.Collection'>,
 <class 'collections.abc.Sized'>,
 <class 'collections.abc.Iterable'>,
 <class 'collections.abc.Container'>,
 <class 'object'>]

この_Environクラスなのですが、__setitem__()__delitem__()が次の様にカスタマイズされています。

class _Environ(MutableMapping):
    def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue):
    [...]
    def __setitem__(self, key, value):
        key = self.encodekey(key)
        value = self.encodevalue(value)
        putenv(key, value)
        self._data[key] = value

    def __delitem__(self, key):
        encodedkey = self.encodekey(key)
        unsetenv(encodedkey)
        try:
            del self._data[encodedkey]
        except KeyError:
            # raise KeyError with the original key value
            raise KeyError(key) from None
    [...]

putenv()unsetenv()は指定されたキーの環境変数を書き換える関数です。

そのため、os.environの値をセット・削除した際に環境変数も自動的に書き換わるのです。


おまけ

os.environはオブジェクト

2020年10月現在の話ですが、

某有名プログラミングスクールさんのブログos.environ()などと書いてありますが、

os.environはオブジェクトです。

os.environ()のようにメソッドで呼ぶことはできません!!


参考書籍

このエントリーをはてなブックマークに追加


関連記事

記事へのコメント