Різниця між 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

Одна спостерігається різниця (Python27):

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


119
ОП запитує про те, os.environ.get()що повертається None(якщо не вказано інше) і ніколи не створює виняток, якщо env. вар. не існує. Ваші заплутані речі при використанні os.environ['TERM']яких не є питанням.
Антон

2
Ор в питання питає про os.environ.get()проти , os.getenv()але тіло також включає в себе os.environvs. os.environ.get()так що ця відповідь правильна , по крайней мере , в деяких відносинах - неповне, але правильний.
FKEinternet

3
Ця неправильна та оманлива відповідь повинна була отримати негативні голоси. Наступна відповідь - правильна.
RayLuo

80

Дивіться цю пов’язану нитку . В основному, os.environвін знаходиться при імпорті і os.getenvє обгорткою для os.environ.get, принаймні, в CPython.

EDIT: відповісти на коментар у 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кинуто", хочете зберегти кілька символів. "
mindthief

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.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 на рівень C, getenvщоб побачити змінні реального середовища після виклику 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, тому я отримую дуже мінімальні витрати.
Преслав

Це було 3.7.1 на macOS Mojave. Терміни були досить послідовними.
fredrik

@PreslavRachev мінімальний чи ні, це додатковий виклик функції, тому є деякі накладні витрати. При цьому, напевно, вам не потрібно отримувати змінні env посередині вашого внутрішнього циклу.
pmav99

7
Зовсім не має значення. Мікрооптимізація одного виклику функції ... Будь-яка програма повинна будь-коли читати навколишнє середовище лише на завантажувальному пристрої, що робить це ще більш неактуальним.
Віктор Шредер

1
BTW, usecє мікросекундою в timeit. Різниця, виявлена ​​в цьому мікро-бенчмаркінгу, становила 0,18 мікросекунди ...
Віктор Шредер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.