Pergunta

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? Eu preciso armazenar a variável global em uma variável local da função que precisa de seu acesso?

Foi útil?

Solução

Você pode usar uma variável global em outras funções, declarando-o 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

Eu imagino que a razão para isso é que, uma vez que as variáveis ??globais são tão perigosos, Python quer ter certeza de que você realmente sabe o que é o que você está jogando com exigindo expressamente a palavra-chave global.

Veja outras respostas se você quiser compartilhar uma variável global em módulos.

Outras dicas

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

Say você tem um Módulo assim:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Você pode esperar para imprimir 42, mas em vez disso ele imprime 5. Como já foi mencionado, se você adicionar uma declaração 'global' para func1(), então func2() imprimirá 42.

def func1():
    global myGlobal
    myGlobal = 42

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

Quando você atribui 42 ao nome myGlobal, portanto, Python cria uma variável local que as sombras a variável global com o mesmo nome. vai que locais fora do escopo e é coleta de lixo quando func1() retornos; Enquanto isso, func2() nunca pode ver nada que não seja o (não modificada) nome global. Note-se que esta decisão namespace acontece em tempo de compilação, não em tempo de execução - se estivesse a ler o valor de myGlobal dentro func1() antes de atribuir a ele, você terá uma UnboundLocalError, porque Python já decidiu que ele deve ser um local de variável, mas ela não teve qualquer valor associado com ele ainda. Mas usando a instrução 'global', você diz Python que ele deve procurar outro lugar para o nome em vez de atribuir a ele localmente.

(Eu acredito que este comportamento se originou grande parte através de uma otimização de namespaces locais - sem este comportamento, VM do Python seria necessário realizar pelo menos três nome de pesquisas cada vez que um novo nome é atribuído a dentro de uma função (para garantir que o nome já não existia no módulo / builtin nível), que iria desacelerar significativamente uma operação muito comum.)

Você pode querer explorar a noção de namespaces . Em Python, o módulo é o lugar natural para Global dados:

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

Um uso específico de mundial-in-a-módulo é descrito aqui - Como posso compartilhar variáveis ??globais em módulos , e para a integralidade dos conteúdos são compartilhados aqui:?

A forma canônica para compartilhar informações através de módulos dentro de um único programa é a criação de um módulo de configuração especial (muitas vezes chamado configuração ou cfg ). Basta importar o módulo de configuração em todos os módulos de sua aplicação; o módulo torna-se então disponível como um nome global. Porque há apenas uma instância de cada módulo, todas as alterações feitas ao objeto módulo se reflete em todos os lugares. Por exemplo:

arquivo: config.py

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

arquivo: mod.py

import config
config.x = 1

arquivo: main.py

import config
import mod
print config.x

Python usa uma simples heurística para decidir qual escopo ele deve carregar uma variável, entre o local eo global. Se uma variável aparece nome do lado esquerdo de uma atribuição, mas não é declarada global, presume-se que seja local. Se ele não aparecer no lado esquerdo de uma atribuiçã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.

Se você quiser para se referir a uma variável global em uma função, você pode usar o Global palavra-chave para declarar quais as variáveis ??são globais. Você não tem que usá-lo em todos os casos (como alguém aqui incorretamente reivindicações) - se o nome referenciado em uma expressão não pode ser encontrado em âmbito local ou escopos nas funções em que esta função é definida, ela é procurada entre mundial variáveis.

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

Além disso, as variáveis ??globais são úteis, ao contrário de alguns fanáticos OOP que afirmam o contrário -. Especialmente para roteiros menores, onde OOP é um exagero

Além de respostas já existentes e para tornar isso mais confuso:

Em Python, variáveis ??que apenas são referenciados dentro de uma função são implicitamente mundial . Se uma variável é atribuído um novo valor em qualquer lugar dentro do corpo da função, é assumido ser um Local . Se uma variável é sempre atribuído um novo valor dentro da função, a variável é implicitamente local, e você precisa declará-la explicitamente como ‘global’.

Embora um pouco surpreendente à primeira vista, um momento de consideração explica isto. Por um lado, exigindo global para variáveis ??atribuídas fornece uma bar contra os efeitos colaterais indesejados. Por outro lado, foi se mundial necessário para todas as referências globais, você estaria usando global de todo o Tempo. Você teria que declarar tão global cada referência a um built-in função ou a um componente de um módulo importado. Esta desordem faria derrotar a utilidade da declaração global para identificar efeitos colaterais.

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

Se eu criar uma variável global em uma função, como eu posso usar essa variável em outra 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' 

Escrevendo uma função na verdade não executar seu código. Então chamamos a função create_global_variable:

>>> create_global_variable()

Usando globals sem modificação

Você pode simplesmente usá-lo, contanto que você não espere para a mudança qual objeto ele aponta para:

Por exemplo,

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

e agora podemos usar a variável global:

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

A modificação da variável global dentro de uma função

Para apontar a variável global em um objeto diferente, você é obrigado a usar a palavra-chave global novamente:

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

Note que depois de escrever esta função, o código realmente alterá-lo ainda não foi executado:

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

Assim, depois de chamar a função:

>>> change_global_variable()

podemos ver que a variável global foi alterado. O nome global_variable agora aponta para 'Bar':

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

Note que "global" em Python não é verdadeiramente global - é apenas global para o nível de módulo. Por isso, é disponível apenas para funções escritas nos módulos em que é global. Funções lembrar o módulo no qual eles são escritos, então quando eles são exportados para outros módulos, eles continuam a olhar no módulo em que eles foram criados para encontrar variáveis ??globais.

As variáveis ??locais com o mesmo nome

Se você criar uma variável local com o mesmo nome, vai 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 usando essa variável local misnamed não muda a variável global:

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

Note que você deve evitar usar as variáveis ??locais com os mesmos nomes que globals se você não sabe exatamente o que você está fazendo e ter uma boa razão para fazê-lo. Eu ainda não encontrei tal razão.

Com a execução paralela, variáveis ??globais pode causar resultados inesperados se você não entende o que está acontecendo. Aqui está um exemplo do uso de 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))

Output:

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]

Como se vê, a resposta é sempre simples.

Aqui está um módulo de amostra pequena, com uma maneira simples de mostrar na definição de uma main:

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

def isTheNumber():
    return helper

Aqui é 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 apenas como aquele, e ele irá executar. Espero que ajude.

O que você está dizendo é usar o método como este:

globvar = 5

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

f()  # Prints 5

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

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

Ambos dão o mesmo resultado.

Você precisa fazer referência a variável global em cada função 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]
"""

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

Se você não tem que especificar explicitamente quando um identificador foi para se referir a um acordo global predefinido, então você provavelmente tem que especificar explicitamente quando um identificador é uma nova variável local em vez (por exemplo, com algo como o ' var comando' visto em JavaScript). Desde 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 tentou adivinhar, usando uma variável global se existisse ou a criação de uma variável local se ele não o fez. No entanto, isso seria muito propenso a erros. Por exemplo, a importação de outro módulo pode inadvertidamente introduzir uma variável global por esse nome, mudando o comportamento do seu programa.

Tente isto:

def x1():
    global x
    x = 6

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

x = 5
x1()
x2()  # output --> 7

No caso de você ter uma variável local com o mesmo nome, você pode querer usar o função globals() .

globals()['your_global_var'] = 42

Na sequência e como um add on, use um arquivo para conter todas as variáveis ??globais todos declarados localmente e, em seguida, import as:

Arquivo initval.py :

Stocksin = 300
Prices = []

Arquivo getstocks.py :

import initval as iv

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


def getmycharts():
    for ic in range(iv.Stocksin):

Escrita de elementos explícitos de uma matriz global aparentemente não precisa a declaração global, embora escrevendo para ele "atacado" tem 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

Referência do namespace classe onde você quer a mudança para aparecer.

Neste exemplo, o corredor está usando max a partir da configuração do arquivo. Eu quero o meu teste para alterar o valor de max quando corredor está a usá-lo.

main / config.py

max = 15000

main / runner.py

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

testes / 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()

Eu estou adicionando isso como eu não vi em nenhuma das outras respostas e que poderia ser útil para alguém lutando com algo semelhante. A marca globals() função retorna um símbolo global mutável dicionário onde você pode "magicamente" dados disponíveis 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

Será que somente permite que você despejar variáveis ??/ carga fora e para dentro do espaço de nomes global. Super conveniente, sem muss, nenhum barulho. Certeza que é Python 3 apenas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top