Como posso criar ou usar uma variável global em uma função?
Se eu criar uma variável global em uma função, como posso usar essa variável global em outra função? Preciso armazenar a variável global em uma variável local da função que precisa de seu acesso?
python
global-variables
scope
user46646
fonte
fonte
global
palavra-chave seja porque os globais são perigosos. Pelo contrário, é porque o idioma não exige que você declare explicitamente variáveis e assume automaticamente que uma variável que você atribui tem escopo de função, a menos que você diga o contrário. Aglobal
palavra-chave é o meio fornecido para dizer o contrário.f2()
estado mudança agoraf3()
poderia fazer algo inesperado As funções podem agora operar agnóstico para o estado programa externo?.Se estou entendendo sua situação corretamente, o que você está vendo é o resultado de como o Python lida com namespaces locais (funções) e globais (módulos).
Digamos que você tenha um módulo como este:
Você pode esperar que isso imprima 42, mas em vez disso imprime 5. Como já foi mencionado, se você adicionar uma
global
declaração ' ' afunc1()
,func2()
imprimirá 42.O que está acontecendo aqui é que o Python assume que qualquer nome atribuído , em qualquer lugar de uma função, é local para essa função, a menos que seja explicitamente dito o contrário. Se estiver apenas lendo um nome e o nome não existir localmente, ele tentará procurar o nome em qualquer escopo que contenha (por exemplo, o escopo global do módulo).
Quando você atribui 42 ao nome
myGlobal
, o Python cria uma variável local que oculta a variável global com o mesmo nome. Esse local sai do escopo e é coletado como lixo quandofunc1()
retorna; enquanto isso,func2()
nunca poderá ver nada além do nome global (não modificado). Observe que essa decisão de namespace ocorre no tempo de compilação, não no tempo de execução - se você lesse o valor demyGlobal
insidefunc1()
antes de atribuir a ele, obteria umUnboundLocalError
, porque o Python já decidiu que deve ser uma variável local, mas ainda não teve nenhum valor associado a ele. Mas, usando aglobal
instrução ' ', você diz ao Python que ele deve procurar o nome em outro lugar, em vez de atribuí-lo localmente.(Acredito que esse comportamento se originou amplamente de uma otimização de namespaces locais - sem esse comportamento, a VM do Python precisaria executar pelo menos três pesquisas de nome cada vez que um novo nome fosse atribuído dentro de uma função (para garantir que o nome não ' já existe no nível do módulo / interno), o que desaceleraria significativamente uma operação muito comum.)
fonte
MyGlobal = 5
x
é local é diferente de verificar no tempo de execução se o nome do local foi associado a um valor antes de ser usado pela primeira vez.MY_GLOBAL = 5
. Veja o Guia de Estilo para Código Python .Você pode explorar a noção de namespaces . No Python, o módulo é o local natural para dados globais :
Um uso específico de global-in-a-module é descrito aqui - Como faço para compartilhar variáveis globais entre módulos? , e para completar, o conteúdo é compartilhado aqui:
fonte
config.x
posso me livrar disso? Eu vim comx = lambda: config.x
e então tenho o novo valor emx()
. por alguma razão, tera = config.x
não faz o truque para mim.from config import x
resolve isso?O Python usa uma heurística simples para decidir de qual escopo deve carregar uma variável, entre local e global. Se um nome de variável aparecer no lado esquerdo de uma atribuição, mas não for declarado global, será considerado local. Se ele não aparecer no lado esquerdo de uma atribuição, será considerado global.
Veja como baz, que aparece no lado esquerdo de uma tarefa em
foo()
, é a únicaLOAD_FAST
variável.fonte
for
loop e o nome afteras
inwith
e asexcept
instruções também estão vinculados.as
de umaexcept
cláusula, isso não era óbvio para mim. Mas é excluído automaticamente para economizar memória.as ...
destino no manipulador de exceções.Se você quiser se referir a uma variável global em uma função, poderá usar a palavra-chave global para declarar quais variáveis são globais. Você não precisa usá-lo em todos os casos (como alguém aqui afirma incorretamente) - se o nome referenciado em uma expressão não puder ser encontrado no escopo ou nos escopos locais nas funções em que essa função é definida, ela será pesquisada entre os globais variáveis.
No entanto, se você atribuir a uma nova variável não declarada como global na função, ela será declarada implicitamente como local e poderá ofuscar qualquer variável global existente com o mesmo nome.
Além disso, variáveis globais são úteis, ao contrário de alguns fanáticos por OOP que afirmam o contrário - especialmente para scripts menores, onde o OOP é um exagero.
fonte
Podemos criar um global com a seguinte função:
Escrever uma função não executa seu código. Então chamamos a
create_global_variable
função:Usando globais sem modificação
Você pode apenas usá-lo, desde que não espere alterar para qual objeto ele aponta:
Por exemplo,
e agora podemos usar a variável global:
Modificação da variável global de dentro de uma função
Para apontar a variável global para um objeto diferente, você deve usar a palavra-chave global novamente:
Observe que, após escrever esta função, o código que realmente a altera ainda não foi executado:
Então, depois de chamar a função:
podemos ver que a variável global foi alterada. O
global_variable
nome agora aponta para'Bar'
:Observe que "global" no Python não é verdadeiramente global - é apenas global no nível do módulo. Portanto, ele está disponível apenas para funções escritas nos módulos em que é global. As funções lembram o módulo em que foram gravadas; portanto, quando são exportadas para outros módulos, elas ainda procuram no módulo em que foram criadas para encontrar variáveis globais.
Variáveis locais com o mesmo nome
Se você criar uma variável local com o mesmo nome, ela irá ofuscar uma variável global:
Mas o uso dessa variável local com nome incorreto não altera a variável global:
Observe que você deve evitar o uso de variáveis locais com os mesmos nomes de globais, a menos que saiba exatamente o que está fazendo e tenha um bom motivo para fazê-lo. Ainda não encontrei esse motivo.
Temos o mesmo comportamento nas aulas
Um comentário a seguir pergunta:
Aqui, demonstro que temos o mesmo comportamento nos métodos que fazemos nas funções regulares:
E agora:
Mas eu sugiro que, em vez de usar variáveis globais, você use atributos de classe, para evitar sobrecarregar o espaço para nome do módulo. Observe também que não usamos
self
argumentos aqui - esses podem ser métodos de classe (úteis se você alterar o atributo de classe docls
argumento usual ) ou métodos estáticos (nãoself
oucls
).fonte
Além das respostas já existentes e para tornar isso mais confuso:
Fonte: Quais são as regras para variáveis locais e globais no Python? .
fonte
Com a execução paralela, variáveis globais podem causar resultados inesperados se você não entender o que está acontecendo. Aqui está um exemplo de uso de uma variável global no multiprocessamento. Podemos ver claramente que cada processo trabalha com sua própria cópia da variável:
Resultado:
fonte
O que você está dizendo é usar o método como este:
Mas a melhor maneira é usar a variável global como esta:
Ambos dão a mesma saída.
fonte
Como se vê, a resposta é sempre simples.
Aqui está um pequeno módulo de amostra com uma maneira simples de mostrá-lo em uma
main
definição:Aqui está como mostrá-lo em uma
main
definição:Esse código simples funciona assim e é executado. Espero que ajude.
fonte
global_vars
e inicializo os dadosinit_global_vars
, que estão sendo chamados no script de inicialização. Então, simplesmente crio o método de acessador para cada var global definida. Espero poder votar isso várias vezes! Obrigado Peter!Você precisa fazer referência à variável global em todas as funções que deseja usar.
Do seguinte modo:
fonte
Na verdade, você não está armazenando o global em uma variável local, apenas criando uma referência local para o mesmo objeto ao qual sua referência global original se refere. Lembre-se de que praticamente tudo no Python é um nome referente a um objeto, e nada é copiado na operação usual.
Se você não precisou especificar explicitamente quando um identificador deveria se referir a um global predefinido, presumivelmente teria que especificar explicitamente quando um identificador é uma nova variável local (por exemplo, com algo como o comando 'var' visto em JavaScript). Como as variáveis locais são mais comuns que as globais em qualquer sistema sério e não trivial, o sistema do Python faz mais sentido na maioria dos casos.
Você poderia ter um idioma que tentasse adivinhar, usando uma variável global se ela existisse ou criando uma variável local se não existisse. No entanto, isso seria muito propenso a erros. Por exemplo, a importação de outro módulo pode inadvertidamente introduzir uma variável global com esse nome, alterando o comportamento do seu programa.
fonte
Tente o seguinte:
fonte
Caso você tenha uma variável local com o mesmo nome, convém usar a
globals()
função .fonte
Após e como complemento, use um arquivo para conter todas as variáveis globais, todas declaradas localmente e, em seguida,
import as
:Arquivo initval.py :
Arquivo getstocks.py :
fonte
import ... as ...
? Por que não apenasimport ...
?global
:-) => +1 :-) Por favor, edite sua resposta para esclarecer esses interrogatórios que outras pessoas também podem ter. CheersA gravação em elementos explícitos de uma matriz global aparentemente não precisa da declaração global, embora a gravação em "atacado" tenha esse requisito:
fonte
Estou adicionando isso porque não o vi em nenhuma das outras respostas e pode ser útil para alguém que está enfrentando algo semelhante. A
globals()
função retorna um dicionário de símbolos globais mutável, no qual você pode "magicamente" disponibilizar dados para o restante do seu código. Por exemplo:e
Apenas permitirá que você faça o dump / carregue variáveis fora e dentro do espaço de nomes global. Super conveniente, sem confusão, sem problemas. Certamente é apenas o Python 3.
fonte
globals()
sempre retorna globais disponíveis no contexto local; portanto, uma mutação aqui pode não refletir em outro módulo.Faça referência ao namespace da classe em que deseja que a alteração seja exibida.
Neste exemplo, o runner está usando max na configuração do arquivo. Quero que meu teste altere o valor de max quando o corredor estiver usando.
main / config.py
main / runner.py
tests / runner_test.py
fonte
Globais estão bem - Exceto no Multiprocessamento
Globais em conexão com o multiprocessamento em diferentes plataformas / ambientes, como Windows / Mac OS, por um lado, e Linux, por outro, são problemáticos.
Vou mostrar isso com um exemplo simples, apontando um problema com o qual me deparo há algum tempo atrás.
Se você quer entender, por que as coisas são diferentes no Windows / MacOs e Linux, você precisa saber disso, o mecanismo padrão para iniciar um novo processo no ...
Eles são diferentes na alocação de memória, uma inicialização ... (mas eu não entendo isso aqui).
Vamos dar uma olhada no problema / exemplo ...
janelas
Se você executar isso no Windows (e suponho também no MacOS), obterá a seguinte saída ...
Linux
Se você executar isso no Linux, obterá o seguinte.
fonte