Diferença entre os.getenv e os.environ.get

159

Existe alguma diferença entre as duas abordagens?

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

Eles parecem ter exatamente a mesma funcionalidade.

André Staltz
fonte

Respostas:

60

Uma diferença observada (Python27):

os.environgera uma exceção se a variável ambiental não existir. os.getenvnão gera uma exceção, mas retorna Nenhum

giwyni
fonte
119
O OP pergunta sobre os.environ.get()quais retornos None(a menos que especificado de forma diferente) e nunca gera uma exceção se o env. var. não existe. Suas coisas confusas com o uso os.environ['TERM']não são do que se trata.
Anthon
2
A pergunta do OP pergunta sobre os.environ.get()vs, os.getenv()mas o corpo também inclui os.environvs., os.environ.get()portanto, essa resposta é correta de pelo menos algumas maneiras - incompleta, mas correta.
FKinternet 01/07/19
3
Esta resposta incorreta e enganosa deveria ter recebido votos negativos negativos. A próxima resposta é a correta.
RayLuo 11/04
80

Veja este tópico relacionado . Basicamente, os.environé encontrado na importação e os.getenvé um wrapper para os.environ.get, pelo menos no CPython.

EDIT: Responder a um comentário, no CPython, os.getenvé basicamente um atalho para os.environ.get; desde que os.environé carregado na importação de os, e somente então, o mesmo vale para os.getenv.

W. Conrad Walden
fonte
1
Na verdade, é, de acordo com o documento oficial: docs.python.org/3/library/os.html
ivanleoncz
1
Do encadeamento relacionado vinculado: "a principal razão para usar os.getenv()é quando [...] você deseja que um valor padrão seja retornado quando um nome de variável de ambiente não for encontrado nas os.environchaves de uma chave, em vez de ter uma KeyErrorou qualquer outra coisa lançada, e você deseja salvar alguns caracteres ".
mindthief
35

No Python 2.7 com o 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

Portanto, podemos concluir que os.getenvé apenas um invólucro simples os.environ.get.

zulu
fonte
16

Embora não haja diferença funcional entre os.environ.gete os.getenv, há uma enorme diferença entre os.putenve configurando entradas os.environ. os.putenvestá quebrado , então você deve usar o padrão os.environ.getsimplesmente para evitar o modo como o os.getenvencoraja a usar os.putenvpara simetria.

os.putenvmuda as variáveis reais do ambiente de nível de sistema operacional, mas de uma forma que não aparece através os.getenv, os.environou qualquer outra forma stdlib de inspecionar variáveis de ambiente:

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

Você provavelmente teria que fazer uma chamada de ctypes para o nível C getenvpara ver as variáveis ​​reais do ambiente após a chamada os.putenv. (Iniciar um subprocesso de shell e solicitar suas variáveis ​​de ambiente também pode funcionar, se você for muito cuidadoso com a fuga e --norc/ --noprofile/ qualquer outra coisa que você precise fazer para evitar a configuração de inicialização, mas parece muito mais difícil acertar.)

user2357112 suporta Monica
fonte
2

Além das respostas acima:

$ 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
fredrik
fonte
Com qual versão do Python você testou. No 3.7.2, os.getenvé apenas um invólucro para os.environ.get, então estou recebendo uma sobrecarga mínima.
Preslav Rachev 7/01/19
Isso foi 3.7.1 no macOS Mojave. Os horários eram bastante consistentes.
fredrik
@PreslavRachev mínimo ou não, é uma chamada de função extra, portanto, há alguma sobrecarga. Dito isto, você provavelmente não precisa recuperar variáveis ​​env no meio do seu loop interno.
pmav99 24/02/19
7
Totalmente irrelevante. Micro-otimização de uma única chamada de função ... Qualquer aplicativo deve ler o ambiente apenas no bootstrap de qualquer maneira, tornando isso ainda mais irrelevante.
Victor Schröder
1
BTW, usecé um microssegundo em timeit. A diferença encontrada neste micro-avaliação comparativa foi 0,18 microssegundos ...
Victor Schröder