Como definir variáveis ​​de ambiente em Python

658

Preciso definir algumas variáveis ​​de ambiente no script python e quero que todos os outros scripts chamados de python vejam o conjunto de variáveis ​​de ambiente.

Se eu fizer

os.environ["DEBUSSY"] = 1`

queixa-se dizendo que 1tem que ser uma corda.

Também quero saber como ler as variáveis ​​de ambiente em python (na parte posterior do script) depois de configurá-lo.

prahallada
fonte
Também relacionado: youtu.be/ScyxIfOuSXs?t=61
Yannic Hamann
Não relacionado à pergunta: eu li essa var. nome como The Cat
ahmed

Respostas:

790

As variáveis ​​de ambiente devem ser cadeias de caracteres, portanto, use

os.environ["DEBUSSY"] = "1"

para definir a variável DEBUSSYpara a sequência 1.

Para acessar essa variável posteriormente, basta usar:

print(os.environ["DEBUSSY"])

Os processos filhos herdam automaticamente as variáveis ​​de ambiente do processo pai - nenhuma ação especial da sua parte é necessária.

Sven Marnach
fonte
20
Em algumas plataformas, a modificação do os.environ não modificará o ambiente do sistema, nem no processo atual nem nos processos filhos. Consulte os documentos para obter mais informações: docs.python.org/2/library/os.html#os.environ
Evan
8
@Evan Pode haver algumas variantes históricas do Unix que não suportam putenv(), mas para o Unixen não há nada que você possa fazer de qualquer maneira. Até a versão antiga do AIX e HPUX com a qual trabalhei o suportava. Se alguém conseguir encontrar um computador que não o suporta hoje, tenho sérias dúvidas de que eles poderão executar o Python nesse computador. :)
Sven Marnach,
3
Cuidado: para citar as referências de @ Evan acima, essas alterações no ambiente afetam os subprocessos iniciados com os.system (), popen () ou fork () e execv (). Em outras palavras, lembre-se de que essa abordagem não modifica a maneira como o programa está sendo executado, apenas a forma como os filhos do programa são executados. É verdade que seu programa pode definir e ler variáveis ​​de ambiente, mas apenas no ambiente que configura para seus filhos. Consulte também: alterar o ambiente de processo atual . Até agora, não encontrei uma maneira de um script Python modificar seu ambiente pai.
COD-REaD
1
@SvenMarnach é o "processo filho declaração automaticamente herdam o ambiente do processo pai verdadeiro para shell como bash.
Krishna Oza
@darth_coder É verdade para todos os processos em sistemas operacionais semelhantes ao Unix. Eu não sei sobre o outro sistema operacional. Observe que as variáveis ​​do shell não são armazenadas no ambiente, a menos que você as exporte.
Sven Marnach
114

Pode ser necessário considerar alguns aspectos adicionais para a robustez do código;

ao armazenar uma variável com valor inteiro como variável de ambiente, tente

os.environ['DEBUSSY'] = str(myintvariable)

para recuperação, considere que, para evitar erros, tente

os.environ.get('DEBUSSY', 'Not Set')

possivelmente substitua '-1' por 'Não definido'

então, para juntar tudo isso

myintvariable = 1
os.environ['DEBUSSY'] = str(myintvariable)
strauss = int(os.environ.get('STRAUSS', '-1'))
# NB KeyError <=> strauss = os.environ['STRAUSS']
debussy = int(os.environ.get('DEBUSSY', '-1'))

print "%s %u, %s %u" % ('Strauss', strauss, 'Debussy', debussy)
Marca
fonte
3
Você pode dizer como definiria a variável em uma máquina Linux. O código é o mesmo para todas as plataformas?
Anurag-Sharma
2
Raramente faz sentido armazenar -1 para um número inteiro ausente. A melhor aposta seria myvar = int(os.environ.get('MYVAR')) if os.environ.get('MYVAR', '') != '' else None- de que maneira seria Nenhum se nenhum número foi fornecido
Benjamin Atkin
1
Se você está lidando com números inteiros, um -1 faz sentido. Embora eu provavelmente defina uma variável / constante para o valor que usaria para não definir (por exemplo, value_not_set = '-1'). Então, você pode usardebussy = int(os.environ.get('DEBUSSY', value_not_set))
yeOldeDataSmythe
68

os.environse comporta como um dicionário python, para que todas as operações comuns do dicionário possam ser executadas. Além das operações gete setmencionadas nas outras respostas, também podemos simplesmente verificar se existe uma chave. As chaves e os valores devem ser armazenados como seqüências de caracteres .

Python 3

Para python 3, os dicionários usam a palavra-chave in em vez de has_key

>>> import os
>>> 'HOME' in os.environ  # Check an existing env. variable
True
...

Python 2

>>> import os
>>> os.environ.has_key('HOME')  # Check an existing env. variable
True
>>> os.environ.has_key('FOO')   # Check for a non existing variable
False
>>> os.environ['FOO'] = '1'     # Set a new env. variable (String value)
>>> os.environ.has_key('FOO')
True
>>> os.environ.get('FOO')       # Retrieve the value
'1'

Há uma coisa importante a ser observada sobre o uso os.environ:

Embora os processos filhos herdem o ambiente do processo pai, eu deparei com um problema recentemente e descobri que, se você tiver outros scripts atualizando o ambiente enquanto o script python estiver em execução, a chamada os.environnovamente não refletirá os valores mais recentes .

Trecho dos documentos :

Esse mapeamento é capturado na primeira vez que o módulo os é importado, normalmente durante a inicialização do Python como parte do processamento do site.py. Alterações no ambiente feitas após esse período não são refletidas no os.environ, exceto as alterações feitas pela modificação direta do os.environ.

os.environ.data que armazena todas as variáveis ​​de ambiente, é um objeto dict, que contém todos os valores do ambiente:

>>> type(os.environ.data)  # changed to _data since v3.2 (refer comment below)
<type 'dict'>
sisanared
fonte
1
As variáveis ​​de ambiente de um processo são definidas quando o processo é criado. Quaisquer alterações feitas depois disso não afetarão a própria cópia do processo da variável de ambiente. Isso é comum a todos os processos, não apenas ao Python. Além disso, os.environ.datafoi renomeado no Python 3.2 para os.environ._data, o prefixo de sublinhado mostrando que você não deve lê-lo diretamente. De qualquer forma, os.environ._datanão terá valores atualizados de qualquer maneira.
Al Sweigart 31/07/19
Sim, eu entendo agora. Eu queria compartilhar minha surpresa inicial com outras pessoas que vêm procurar. Obrigado por apontar a atualização para o nome da variável desde 3.2, atualizará a resposta.
Sisanared
21

se eu fizer os.environ ["DEBUSSY"] = 1, ele reclama dizendo que 1 deve ser uma string.

Então faça

os.environ["DEBUSSY"] = "1"

Eu também quero saber como ler as variáveis ​​de ambiente em python (na parte posterior do script) depois de configurá-lo.

Basta usar os.environ["DEBUSSY"], como em

some_value = os.environ["DEBUSSY"]
Jim Brissom
fonte
19

para definir variável:

item Método de atribuição usando a chave:

import os    
os.environ['DEBUSSY'] = '1'  #Environ Variable must be string not Int

para obter ou verificar se existe ou não,

Como os.environ é uma instância, você pode tentar o caminho do objeto.

Método 1:

os.environ.get('DEBUSSY') # this is error free method if not will return None by default

receberá '1'como valor de retorno

Método 2:

os.environ['DEBUSSY'] # will throw an key error if not found!

Método 3:

'DEBUSSY' in os.environ  # will return Boolean True/False

Método 4:

os.environ.has_key('DEBUSSY') #last 2 methods are Boolean Return so can use for conditional statements
Mohideen bin Mohammed
fonte
16

Você deve atribuir o valor da string à variável de ambiente.

os.environ["DEBUSSY"] = "1"

Se você quiser ler ou imprimir a variável de ambiente, use

print os.environ["DEBUSSY"]

Essas alterações serão efetivas apenas para o processo atual em que foram atribuídas, não alterando o valor permanentemente. Os processos filhos herdarão automaticamente o ambiente do processo pai.

insira a descrição da imagem aqui

RejeeshChandran
fonte
5
"Essas alterações serão efetivas apenas para o processo atual em que foram atribuídas, não alterarão o valor permanentemente." Isso respondeu a uma pergunta que eu tinha sobre o escopo de definir uma variável de ambiente.
Spitfiredd
2
Se eu sair do shell python, e o ambiente OS configurado anteriormente se foi.
MeadowMuffins
Como faço para definir uma variável de ambiente no Windows? Eu tentei, set [<name>=[<value>]]mas apenas o faz para o atual processo em execução. Quando fecho o cmd, ele não existe e mesmo quando está aberto, outros programas não conseguem vê-lo.
Filip
15

Que tal os.environ["DEBUSSY"] = '1'? Variáveis ​​de ambiente são sempre strings.

ThiefMaster
fonte
14

Eu tenho tentado adicionar variáveis ​​de ambiente. Meu objetivo era armazenar algumas informações do usuário em variáveis ​​do sistema, para que eu possa usá-las em soluções futuras, como uma alternativa aos arquivos de configuração. No entanto, o método descrito no código abaixo não me ajudou em nada.

import os
os.environ["variable_1"] = "value_1"
os.environ["variable_2"] = "value_2"
# To Verify above code
os.environ.get("variable_1")
os.environ.get("variable_2")

Esse simples bloco de código funciona bem, no entanto, essas variáveis ​​existem dentro dos respectivos processos, de modo que você não as encontrará na guia de variáveis ​​de ambiente das configurações do sistema Windows. Muito acima do código não serviu ao meu propósito. Esse problema é discutido aqui: problema de economia de variável

os.environ.putenv(key, value)

Outra tentativa mal sucedida. Então, finalmente, consegui salvar a variável com sucesso dentro do registro do ambiente da janela, imitando os comandos do shell do windows envolvidos na classe do sistema do pacote os. O código a seguir descreve essa tentativa bem-sucedida.

os.system("SETX {0} {1} /M".format(key, value))

Espero que isso seja útil para alguns de vocês.

Sourabh Desai
fonte
12

Deve-se observar que, se você tentar definir a variável de ambiente como uma avaliação do bash, ela não armazenará o que você espera. Exemplo:

from os import environ

environ["JAVA_HOME"] = "$(/usr/libexec/java_home)"

Isso não avaliará como faz em um shell; portanto, em vez de ficar /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Homecomo um caminho, você obterá a expressão literal $(/usr/libexec/java_home).

Avalie-o antes de definir a variável de ambiente, da seguinte maneira:

from os import environ
from subprocess import Popen, PIPE

bash_variable = "$(/usr/libexec/java_home)"
capture = Popen(f"echo {bash_variable}", stdout=PIPE, shell=True)
std_out, std_err = capture.communicate()
return_code = capture.returncode

if return_code == 0:
    evaluated_env = std_out.decode().strip()
    environ["JAVA_HOME"] = evaluated_env
else:
    print(f"Error: Unable to find environment variable {bash_variable}")
Josh Correia
fonte
11

Você pode usar o os.environdicionário para acessar suas variáveis ​​de ambiente.

Agora, um problema que tive foi que, se eu tentasse usar os.systemum arquivo em lotes que define suas variáveis ​​de ambiente (usando o comando SET em um arquivo **. Bat *), ele realmente não as definiria para o seu ambiente python (mas para o processo filho que é criado com a os.systemfunção). Para realmente obter as variáveis ​​definidas no ambiente python, eu uso este script:

import re
import system
import os

def setEnvBat(batFilePath, verbose = False):
    SetEnvPattern = re.compile("set (\w+)(?:=)(.*)$", re.MULTILINE)
    SetEnvFile = open(batFilePath, "r")
    SetEnvText = SetEnvFile.read()
    SetEnvMatchList = re.findall(SetEnvPattern, SetEnvText)

    for SetEnvMatch in SetEnvMatchList:
        VarName=SetEnvMatch[0]
        VarValue=SetEnvMatch[1]
        if verbose:
            print "%s=%s"%(VarName,VarValue)
        os.environ[VarName]=VarValue
Ricardo Alejos
fonte
9

Ao jogar com variáveis ​​de ambiente (adicionar / modificar / remover variáveis), uma boa prática é restaurar o estado anterior na conclusão da função.

Você pode precisar de algo como o modified_environgerenciador de contexto descrito nesta pergunta para restaurar as variáveis ​​de ambiente.

Uso clássico:

with modified_environ(DEBUSSY="1"):
    call_my_function()
Laurent LAPORTE
fonte