Разница между os.getenv и os.environ.get

Есть ли разница между обоими подходами?

>>> 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

Кажется, они имеют одинаковую функциональность.

Ответ 1

Наблюдается одно различие (Python27):

os.environ вызывает исключение, если переменная окружения не существует. os.getenv не вызывает исключение, но возвращает None

Ответ 2

Смотрите эту связанную тему. В принципе, os.environ найден при импорте, а os.getenv - это оболочка для os.environ.get, по крайней мере, в CPython.

EDIT: для ответа на комментарий, в CPython, os.getenv - это в основном ярлык для os.environ.get; поскольку os.environ загружается при импорте os, и только тогда, то же самое относится к os.getenv.

Ответ 3

В 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.

Ответ 4

В дополнение к ответам выше:

$ 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

Ответ 5

Хотя между os.environ.get и os.getenv нет функциональной разницы, между os.putenv и настройкой записей в os.environ. os.putenv сломана, так что вы должны по умолчанию os.environ.get просто избежать пути os.getenv рекомендует использовать os.putenv для симметрии.

os.putenv изменяет фактические переменные среды уровня ОС, но таким способом, который не отображается через os.getenv, os.environ или любой другой способ проверки переменных окружения в stdlib:

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

Вам, вероятно, придется сделать вызов ctypes для getenv уровня C, чтобы увидеть реальные переменные среды после вызова os.putenv. (Запуск подпроцесса оболочки и запрос его переменных среды могут также работать, если вы очень осторожны с экранированием и --norc/--noprofile/чем-либо еще, что вам нужно сделать, чтобы избежать настройки при запуске, но это кажется намного сложнее чтобы получить права.)