Usar variáveis globais numa função

Como posso criar ou usar uma variável global numa função?

Se eu criar uma variável global numa função, como posso usar essa variável global noutra função? Preciso armazenar a variável global em uma variável local da função que precisa de seu acesso?

Author: Aran-Fey, 2009-01-08

18 answers

Você pode usar uma variável global noutras funções declarando-a como global em cada função que lhe atribui:

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

Imagino que a razão para isso seja que, uma vez que as variáveis globais são tão perigosas, o Python quer certificar-se de que você realmente sabe que é com isso que está a jogar, exigindo explicitamente a palavra-chave global.

Veja outras respostas se quiser partilhar uma variável global entre módulos.

 3587
Author: Paul Stephenson, 2016-12-01 03:40:54

Se eu estou entendendo a sua situação corretamente, o que você está vendo é o resultado de como Python lida com espaços de nomes locais (função) e globais (módulo).

Digamos que tens um módulo como este.
# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()
Pode esperar que isto publique 42, mas em vez disso imprime 5. Como já foi mencionado, se adicionar uma declaração 'global ' a func1(), então func2() irá imprimir 42.
def func1():
    global myGlobal
    myGlobal = 42

O que se passa aqui é que o Python assume que qualquer nome atribuído a para , em qualquer lugar dentro de uma função, é local para essa função, a menos que explicitamente dito o contrário. Se for apenas a ler a partir de um nome, e o nome não existir localmente, ele tentará procurar o nome em quaisquer âmbitos contendo (por exemplo, o escopo global do módulo).

Quando atribui 42 ao nome myGlobal, Como tal, o Python cria uma variável local que esconde a variável global do mesmo nome. Esse local sai do âmbito e é recolhido do lixo quando func1() devolve; entretanto, func2() nunca poderá ver nada além do nome global (não modificado). Lembre-se que esta decisão do espaço de nomes acontece na hora de compilação, não na hora de execução -- se você tiver que ler o valor de myGlobal dentro de func1() antes de atribuir a ele, você terá um UnboundLocalError, porque o Python já decidiu que deve ser uma variável local, mas ainda não tem nenhum valor associado a ela. Mas usando a Declaração ' global', você diz ao Python que ele deve procurar em outro lugar o nome em vez de atribuindo-o localmente.

(eu acredito que esse comportamento originado em grande parte através de uma otimização do local de namespaces -- sem esse comportamento, Python VM seria necessário realizar, pelo menos, três pesquisas de nome cada vez que um novo nome seja atribuído para dentro de uma função (para garantir que o nome já não existe no módulo/builtin nível), o que poderia reduzir significativamente uma forma muito comum de operação.)

 678
Author: Jeff Shannon, 2015-03-16 18:01:50

Você pode querer explorar a noção de espaços de nomes . Em Python, o módulo é o local natural para global Dados:

Cada módulo tem a sua própria tabela de símbolos privados, que é usada como a tabela de símbolos globais por todas as funções definidas no módulo. Assim, o autor de um módulo pode usar variáveis globais no módulo sem se preocupar com confrontos acidentais com variáveis globais de um usuário. Por outro lado, se você sabe o que está fazendo você pode tocar as variáveis globais de um módulo com a mesma notação usada para se referir às suas funções, modname.itemname.

Uma utilização específica do global-in-a-module é descrita aqui - how-do-i-share-global-variables-across-modules, e para completar o conteúdo é partilhado aqui:

A maneira canônica de compartilhar informações através de módulos dentro de um ÚNICO programa é criar um módulo de configuração especial (muitas vezes chamado de configuração ou cfg). Basta importar o módulo de configuração em todos os módulos de sua aplicação; o módulo então fica disponível como um nome global. Como há apenas uma instância de cada módulo, quaisquer mudanças feitas no objeto do módulo são refletidas em todos os lugares. Por exemplo:

Ficheiro: config.py

x = 0   # Default value of the 'x' configuration setting

Ficheiro: mod.py

import config
config.x = 1

Ficheiro: main.py

import config
import mod
print config.x
 180
Author: gimel, 2018-05-24 12:07:01

O Python usa uma heurística simples para decidir de que âmbito deve carregar uma variável, entre local e global. Se um nome de variável aparece no lado esquerdo de uma atribuição, mas não é declarado global, assume-se que é local. Se não aparecer no lado esquerdo de uma missão, presume-se que seja global.

>>> import dis
>>> def foo():
...     global bar
...     baz = 5
...     print bar
...     print baz
...     print quux
... 
>>> dis.disassemble(foo.func_code)
  3           0 LOAD_CONST               1 (5)
              3 STORE_FAST               0 (baz)

  4           6 LOAD_GLOBAL              0 (bar)
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  5          11 LOAD_FAST                0 (baz)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       

  6          16 LOAD_GLOBAL              1 (quux)
             19 PRINT_ITEM          
             20 PRINT_NEWLINE       
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        
>>> 

Veja como baz, que aparece no lado esquerdo de uma atribuição em foo(), é a única variável LOAD_FAST.

 76
Author: SingleNegationElimination, 2011-07-12 12:35:08

Se quiser referir-se a uma variável global numa função, pode usar a palavra-chave global para declarar quais as variáveis que são globais. Você não tem que usá - lo em todos os casos (como alguém aqui afirma incorretamente) - se o nome referenciado em uma expressão não pode ser encontrado no escopo local ou âmbitos nas funções em que esta função é definida, ele é pesquisado entre as variáveis globais.

No entanto, se atribuir a uma nova variável não declarada como global na função, é implicitamente declarado como local, e pode ofuscar qualquer variável global existente com o mesmo nome.

Também, variáveis globais são úteis, ao contrário de alguns OOP zelotes que afirmam o contrário-especialmente para scripts menores, onde OOP é exagerado.

 50
Author: J S, 2017-03-04 22:00:48

Além das respostas já existentes e para tornar isto mais confuso:

Em Python, as variáveis que só são referenciadas dentro de uma função são: Implicitamente global . Se for atribuído a uma variável um novo valor em qualquer lugar dentro do corpo da função, assume-se que é um local. Se for uma variável é sempre atribuído um novo valor dentro da função, a variável é implicitamente local, e você precisa declará-lo explicitamente como "global".

Mas um pouco. surpreendente no início, um momento de consideração explica presente. Por um lado, a exigência de um valor global para as variáveis atribuídas fornece uma barra contra efeitos secundários não intencionais. Por outro lado, se a global necessário para todas as referências globais, você estaria usando global todos os tempo. Você teria que declarar como global todas as referências a um embutido função ou a um componente de um módulo importado. Esta confusão derrota a utilidade da declaração global para identificar secundario.

Fonte: quais são as regras para variáveis locais e globais em Python?.

 38
Author: Rauni Lillemets, 2014-07-20 10:36:29

Se eu criar uma variável global numa função, como posso usar essa variável noutra função?

Podemos criar um global com a seguinte função:

def create_global_variable():
    global global_variable # must declare it to be a global first
    # modifications are thus reflected on the module's global scope
    global_variable = 'Foo' 

Escrever uma função não executa o seu código. Então chamamos a função create_global_variable:

>>> create_global_variable()

Usando globais sem modificação

Podes usá-lo, desde que não esperes mudar para que objecto aponta:

Por exemplo,

def use_global_variable():
    return global_variable + '!!!'

E agora podemos usar a variável global:

>>> use_global_variable()
'Foo!!!'

Modificação da variável global a partir do interior de uma função

Para apontar a variável global para um objecto diferente, é necessário usar a palavra-chave global de novo:

def change_global_variable():
    global global_variable
    global_variable = 'Bar'

Note que depois de escrever esta função, o código que a alterou ainda não funcionou:

>>> use_global_variable()
'Foo!!!'

Então depois de chamar a função:

>>> change_global_variable()
Podemos ver que a variável global foi alterada. O global_variable o nome agora aponta para 'Bar':
>>> use_global_variable()
'Bar!!!'

Note que "global" em Python não é verdadeiramente global - é apenas global ao nível dos módulos. Portanto, só está disponível para funções escritas nos módulos em que é global. As funções recordam o módulo em que são escritas, por isso, quando são exportadas para outros módulos, continuam a procurar no módulo em que foram criadas para encontrar variáveis globais.

Variáveis locais com o mesmo nome

Se criar uma variável local com o mesmo nome, irá ofuscar uma variável global:

def use_local_with_same_name_as_global():
    # bad name for a local variable, though.
    global_variable = 'Baz' 
    return global_variable + '!!!'

>>> use_local_with_same_name_as_global()
'Baz!!!'

Mas usar essa variável local mal nominada não altera a variável global:

>>> use_global_variable()
'Bar!!!'

Note que você deve evitar usar as variáveis locais com os mesmos nomes que os globais, a menos que você saiba exatamente o que está fazendo e tenha uma boa razão para fazê-lo. Ainda não encontrei essa razão.

 32
Author: Aaron Hall, 2016-07-20 16:32:18
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 usar uma variável global dentro de multiprocessamento. Podemos ver claramente que cada processo funciona com a sua própria cópia da variável:
import multiprocessing
import os
import random
import sys
import time

def worker(new_value):
    old_value = get_value()
    set_value(random.randint(1, 99))
    print('pid=[{pid}] '
          'old_value=[{old_value:2}] '
          'new_value=[{new_value:2}] '
          'get_value=[{get_value:2}]'.format(
          pid=str(os.getpid()),
          old_value=old_value,
          new_value=new_value,
          get_value=get_value()))

def get_value():
    global global_variable
    return global_variable

def set_value(new_value):
    global global_variable
    global_variable = new_value

global_variable = -1

print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after  set_value(), get_value() = [%s]' % get_value())

processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))

Resultado:

before set_value(), get_value() = [-1]
after  set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]
 29
Author: Bohdan, 2017-01-03 02:34:20

É necessário referenciar a variável global em todas as funções que deseja usar.

Como se segue:

var = "test"

def printGlobalText():
    global var #wWe are telling to explicitly use the global version
    var = "global from printGlobalText fun."
    print "var from printGlobalText: " + var

def printLocalText():
    #We are NOT telling to explicitly use the global version, so we are creating a local variable
    var = "local version from printLocalText fun"
    print "var from printLocalText: " + var

printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""
 20
Author: Mohamed El-Saka, 2015-02-04 18:45:42

O que estás a dizer é para usar o método assim:

globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5

Mas a melhor maneira é usar a variável global como esta:

globavar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5

Ambos dão a mesma saída.

 20
Author: gxyd, 2018-04-24 06:25:26
A resposta é sempre simples.

Aqui está um pequeno módulo de amostra com uma forma simples de o mostrar numa definição main:

def five(enterAnumber,sumation):
    global helper
    helper  = enterAnumber + sumation

def isTheNumber():
    return helper

Aqui está como mostrá-lo em uma definição main:

import TestPy

def main():
    atest  = TestPy
    atest.five(5,8)
    print(atest.isTheNumber())

if __name__ == '__main__':
    main()
Este código simples funciona assim e vai ser executado. Espero que ajude.
 19
Author: user2876408, 2018-09-28 11:34:54

Você não está realmente armazenando o global em uma variável local, apenas criando uma referência local ao mesmo objeto a que sua referência global original se refere. Lembre-se que praticamente tudo em Python é um nome que se refere a um objeto, e nada é copiado na operação habitual.

Se não tiver de especificar explicitamente quando um identificador se refere a um global predefinido, então terá de indicar explicitamente quando um identificador é uma nova variável local em vez disso (por exemplo, com algo como o comando 'var' visto em JavaScript). Uma vez que as variáveis locais são mais comuns do que as variáveis globais em qualquer sistema sério e não trivial, o sistema de Python faz mais sentido na maioria dos casos.

Você poderia ter uma linguagem que tentasse adivinhar, usando uma variável global se existisse ou criando uma variável local se não existisse. no entanto, isso seria muito propenso a erros. Por exemplo, importar outro módulo poderia inadvertidamente introduzir um variável global com esse nome, mudando o comportamento de seu programa.

 18
Author: Kylotan, 2011-05-30 21:09:51

Tenta isto:

def x1():
    global x
    x = 6

def x2():
    global x
    x = x+1
    print x

x = 5
x1()
x2()  # output --> 7
 15
Author: Sagar Mehta, 2018-06-20 21:55:48

A seguir e como um add on, use um ficheiro para conter todas as variáveis globais declaradas localmente e depois 'importar como':

Ficheiro initval.py

Stocksin = 300
Prices = []

Ficheiro getstocks.py

import  initval as  iv

Def   getmystocks (): 
     iv.Stocksin  = getstockcount ()


Def getmycharts ():
    For ic in range (0,iv.Stocksin):

.....

 12
Author: Peter Mortensen, 2017-03-04 22:03:12

Escrever a elementos explícitos de uma matriz global aparentemente não precisa da declaração global, embora escrever-lhe "grossista" tenha esse requisito:

import numpy as np

hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])

def func1():
    global hostValue    # mandatory, else local.
    hostValue = 2.0

def func2():
    global hostValue    # mandatory, else UnboundLocalError.
    hostValue += 1.0

def func3():
    global hostArray    # mandatory, else local.
    hostArray = np.array([14., 15.])

def func4():            # no need for globals
    hostArray[0] = 123.4

def func5():            # no need for globals
    hostArray[1] += 1.0

def func6():            # no need for globals
    hostMatrix[1][1] = 12.

def func7():            # no need for globals
    hostMatrix[0][0] += 0.33

func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix
 11
Author: Mike Lampton, 2016-01-08 22:35:22

No caso de ter uma variável local com o mesmo nome, poderá querer usar o globals() Função

globals()['your_global_var'] = 42
 9
Author: Martin Thoma, 2017-04-07 19:15:55

Consulte o espaço de nomes da classe onde quer que a mudança apareça.

Neste exemplo, o runner está a usar max da configuração do ficheiro. Quero que o meu teste altere o valor de max quando o runner o estiver a usar.

Main/config.py

max = 15000

Main/runner.py

from main import config
def check_threads():
    return max < thread_count 

Tests/runner_test.py

from main import runner                # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
   def test_threads(self):
       runner.max = 0                  # <----- 2. set global 
       check_threads()
 5
Author: llewellyn falco, 2017-08-19 08:48:27
Estou a acrescentar isto, porque não o vi em nenhuma das outras respostas e pode ser útil para alguém a lutar com algo semelhante. A função globals () devolve um dicionário de símbolos globais mutáveis onde você pode "magicamente" disponibilizar dados para o resto do seu código. Por exemplo:
from pickle import load
def loaditem(name):
    with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
        globals()[name] = load(openfile)
    return True

E

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

Vai deixar-te descarregar / carregar variáveis de e para o espaço de nomes global. Muito conveniente, sem confusões, sem problemas. Tenho a certeza que é só python 3.

 5
Author: Rafaël Dera, 2017-09-05 14:59:14