Qual é uma boa prática para verificar se uma variável ambiental existe ou não?


130

Quero verificar meu ambiente quanto à existência de uma variável, digamos "FOO", em Python. Para esse fim, estou usando a osbiblioteca padrão. Depois de ler a documentação da biblioteca, descobri duas maneiras de atingir meu objetivo:

Método 1:

if "FOO" in os.environ:
    pass

Método 2:

if os.getenv("FOO") is not None:
    pass

Gostaria de saber qual método, se houver, é um condicional bom / preferido e por quê.


É principalmente baseado em opiniões. Ambos servem ao mesmo propósito. I vai preferir o método 1, uma vez que é mais limpo
— Moinuddin Quadri

1
Não posso dizer que há algo nele. Escolha uma (jogue uma moeda?) E reavalie depois se ela não funcionar. Sinceramente, acho que você passou mais tempo digitando esta pergunta do que economizaria de qualquer maneira!
— jonrsharpe

1
@Ayoub: Acho que você esqueceu de ver a pergunta "Qual é uma boa prática para verificar se uma variável ambiental existe ou não no Python?"
— Moinuddin Quadri

1
Opinião baseada. A sintaxe do método 1 serve melhor, já que você pergunta se fooestá nos envários, não se procura fooresultados em Nonevalores.
— Uriel

1
Mas dessa forma pode não ser óbvio, a menos que você seja holandês ...
— jonrsharpe

Respostas:


168

Use o primeiro; ele tenta diretamente verificar se algo está definido environ. Embora a segunda forma funcione igualmente bem, ela está faltando semanticamente, pois você recebe um valor de volta, se existir, e o usa apenas para comparação.

Você está tentando ver se algo está presente em environ , por que você iria ficar apenas para compará-lo e depois lançá-lo afastado ?

É exatamente getenvisso que faz:

Obtenha uma variável de ambiente e retorne Nonese ela não existir. O segundo argumento opcional pode especificar um padrão alternativo.

(isso também significa que seu cheque pode ser apenas if getenv("FOO"))

você não deseja obtê-lo , deseja verificar sua existência.

De qualquer forma, getenvé apenas um invólucroenviron.get mas você não vê pessoas verificando a associação em mapeamentos com:

from os import environ
if environ.get('Foo') is not None:

Para resumir, use:

if "FOO" in os.environ:
    pass

se você apenas deseja verificar a existência, enquanto, use getenv("FOO")se você realmente deseja fazer algo com o valor que você pode obter.


2
Obrigado pela sua explicação. Manterei isso em mente.
— Kshitij Saraogi

29

Há um caso para qualquer solução, dependendo do que você deseja fazer, dependendo da existência da variável de ambiente.

Caso 1

Quando você deseja executar ações diferentes com base na existência da variável de ambiente, sem se importar com seu valor, a primeira solução é a melhor prática. Descreve sucintamente o que você testa: é 'FOO' na lista de variáveis ​​de ambiente.

if 'KITTEN_ALLERGY' in os.environ:
    buy_puppy()
else:
    buy_kitten()

Caso 2

Quando você deseja definir um valor padrão, se o valor não for definido nas variáveis ​​de ambiente, a segunda solução é realmente útil, embora não no formato que você escreveu:

server = os.getenv('MY_CAT_STREAMS', 'youtube.com')

ou talvez

server = os.environ.get('MY_CAT_STREAMS', 'youtube.com')

Observe que, se você tiver várias opções para o seu aplicativo, poderá procurar ChainMap, o que permite mesclar vários dictos com base em chaves. Há um exemplo disso na ChainMapdocumentação:

[...]
combined = ChainMap(command_line_args, os.environ, defaults)

15

Para estar no lado seguro, use

os.getenv('FOO') or 'bar'

Um caso de canto com as respostas acima é quando a variável de ambiente está definida, mas está vazia

Para este caso especial, você obtém

print(os.getenv('FOO', 'bar'))
# prints new line - though you expected `bar`

ou

if "FOO" in os.environ:
    print("FOO is here")
# prints FOO is here - however its not

Para evitar isso, use or

os.getenv('FOO') or 'bar'

Então você recebe

print(os.getenv('FOO') or 'bar')
# bar

Quando temos variáveis ​​de ambiente vazias?

Você esqueceu de definir o valor no .envarquivo

# .env
FOO=

ou exportado como

$ export FOO=

ou esqueceu de configurá-lo settings.py

# settings.py
os.environ['FOO'] = ''

Atualização: em caso de dúvida, confira essas orientações

>>> import os; os.environ['FOO'] = ''; print(os.getenv('FOO', 'bar'))

$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"

A assinatura para getenv é def getenv(key, default=None):assim que se forma que deve permitir um padrão vs o ou sintaxe no início
— Chris McKee

@Chris McKee tente isto #>>> import os; os.environ['FOO'] = ''; print(os.getenv('FOO', 'bar'))
— Levon

Assinatura enganosa do método
— Chris

1
@ Chris McKee, outro exemplo$ FOO= python -c "import os; print(os.getenv('FOO', 'bar'))"
— Levon

3

Caso deseje verificar se várias variáveis ​​env não estão definidas, você pode fazer o seguinte:

import os

MANDATORY_ENV_VARS = ["FOO", "BAR"]

for var in MANDATORY_ENV_VARS:
    if var not in os.environ:
        raise EnvironmentError("Failed because {} is not set.".format(var))

-1

Meu comentário pode não ser relevante para as tags fornecidas. No entanto, fui levado a esta página da minha pesquisa. Eu estava procurando uma verificação semelhante no R e vim a seguir com a ajuda do post @hugovdbeg. Espero que seja útil para alguém que está procurando uma solução semelhante em R

'USERNAME' %in% names(Sys.getenv())
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.