Jak mogę utworzyć lub używać zmiennej globalnej w funkcji?

Jeśli utworzę zmienną globalną w jednej funkcji, jak mogę używać zmiennej globalnej w innej funkcji? Czy muszę przechowywać zmienną globalną w lokalnej zmiennej funkcji, która wymaga jego dostępu?

3287
user46646 8 styczeń 2009, 08:45

18 odpowiedzi

Najlepsza odpowiedź

Możesz użyć zmiennej globalnej w innych funkcjach, deklarując go jako global w każdej funkcji, która przypisuje to:

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

Wyobrażam sobie, że dla tego jest to, że ponieważ zmienne globalne są tak niebezpieczne, python chce się upewnić, że naprawdę wiesz, że to właśnie grasz przez wyraźnie wymagający słowa kluczowego {x0}}.

Zobacz inne odpowiedzi, jeśli chcesz podzielić się zmienną globalną przez moduły.

4444
Rayner Da Cruz 11 sierpień 2020, 21:32

Jeśli prawidłowo rozumiem twoją sytuację, to, co widzisz, jest wynikiem, jak Python obsługuje przestrzeń nazw lokalnej (funkcji) i global (module).

Powiedz, że masz taki moduł:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Możesz spodziewać się tego drukować 42, ale zamiast tego drukuje 5. Jak już wspomniano, jeśli dodasz deklarację "global", a następnie func2() wydrukuje 42.

def func1():
    global myGlobal
    myGlobal = 42

Tutaj dzieje się, że Python zakłada, że każda nazwa, która jest przypisana do do , w dowolnym miejscu w funkcji, jest lokalna do tej funkcji, chyba że wyraźnie powiedziano inaczej. Jeśli jest to tylko czytanie z nazwiska, a nazwa nie istnieje lokalnie, spróbuje wyszukać nazwę w dowolnych zakresach zawierających (np. Globalny zakres modułu).

Po przypisaniu 42 do nazwy myGlobal, Dlatego Python tworzy zmienną lokalną, która cienie zmienną globalną o tej samej nazwie. Ten lokalny wychodzi poza zakres i jest zebrany na śmieci kiedy {{x1 }} zwroty; Tymczasem func2() nigdy nie widzi nic innego niż (niezmodyfikowanej) nazwy globalnej. Należy pamiętać, że ta decyzja przestrzeni nazw nastąpi w czasie kompilacji, nie w czasie wykonywania - jeśli miałbyś odczytać wartość myGlobal wewnątrz func1() przed przypisaniem do niego, otrzymasz UnboundLocalError , Ponieważ Python zdecydował już, że musi być zmienną lokalną, ale nie miało jeszcze żadnej wartości. Ale za pomocą oświadczenia "global", mówisz Pythonie, że powinien wyglądać gdzie indziej do nazwy zamiast przypisywać do niego lokalnie.

(Uważam, że zachowanie to powstało w dużej mierze poprzez optymalizację miejscowych przestrzeni nazw - bez tego zachowania, VM Pythona musiałby wykonywać co najmniej trzy nazwiska w każdym razie, gdy nowa nazwa jest przypisana do wewnątrz funkcji (aby zapewnić, że nazwa nie T już istnieje na poziomie modułu / wbudowanego), który znacznie spowolniłoby bardzo powszechne.)

791
Michael 16 marzec 2015, 18:01

Możesz zwiedzić pojęcie pojęcia przestrzeni nazw. W python, Moduł jest naturalnym miejscem dla global :

Każdy moduł ma własną prywatną tabelę symbolu, który jest używany jako tabelę symbolu globalnego przez wszystkie funkcje zdefiniowane w module. W ten sposób autor modułu może używać zmiennych globalnych w module, nie martwiąc się o przypadkowe starcia z zmiennymi globalnymi użytkownika. Z drugiej strony, jeśli wiesz, co robisz, możesz dotknąć globalnych zmiennych modułu o tym samym notacji, który odnoszą się do swoich funkcji, modname.itemname.

Opisany jest tutaj określone zastosowanie global-in-a-module -

Kanoniczny sposób udostępniania informacji w modułach w jednym programie jest utworzenie specjalnego modułu konfiguracyjnego (często nazywane config lub CFG ). Wystarczy zaimportować moduł konfiguracji we wszystkich modułach aplikacji; Następnie moduł staje się dostępny jako globalna nazwa. Ponieważ istnieje tylko jedna instancja każdego modułu, wszelkie zmiany w obiekcie modułu odzwierciedlają się wszędzie. Na przykład:

Plik: Config.py.

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

Plik: Mod.py.

import config
config.x = 1

Plik: Main.py.

import config
import mod
print config.x
236
congusbongus 16 grudzień 2020, 04:50

Python wykorzystuje prosty heurystyczny, aby zdecydować, który zakres powinien załadować zmienną, między lokalnymi i światowymi. Jeśli nazwa zmiennej pojawi się po lewej stronie zadania, ale nie jest zadeklarowany globalny, zakłada się, że jest lokalny. Jeśli nie pojawia się po lewej stronie zadania, zakłada się, że jest globalny.

>>> 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        
>>> 

Zobacz, jak Baz, który pojawia się po lewej stronie przypisania w foo(), jest jedyną zmienną LOAD_FAST.

97
SingleNegationElimination 12 lipiec 2011, 12:35

Jeśli chcesz odnieść się do zmiennej globalnej w funkcji, możesz użyć słowa kluczowego Global , aby zadeklarować, które zmienne są globalne. Nie musisz go używać we wszystkich przypadkach (jak ktoś tu nieprawidłowo twierdzi) - jeśli nazwa odnosząca się w wyrażeniu nie można znaleźć w zakresie lokalnym lub zakresie w zakresie funkcji, w których ta funkcja jest zdefiniowana, spojrzał wśród globalnych zmienne.

Jednakże, jeśli przypisujesz nową zmienną, która nie została zadeklarowana jako globalna w funkcji, jest domyślnie zadeklarowany jako lokalny, i może przećwiczyć dowolną istniejącą zmienną globalną o tej samej nazwie.

Również globalne zmienne są przydatne, w przeciwieństwie do niektórych OOP Zelotów, którzy twierdzą inaczej - zwłaszcza dla mniejszych skryptów, gdzie OOP jest przesadny.

64
Peter Mortensen 4 marzec 2017, 22:00

Jeśli utworzę zmienną globalną w jednej funkcji, jak mogę użyć tej zmiennej w innej funkcji?

Możemy stworzyć globalny z następującą funkcją:

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' 

Pisanie funkcji nie uruchamia swojego kodu. Nazywamy funkcję create_global_variable:

>>> create_global_variable()

Używanie globalów bez modyfikacji

Możesz go po prostu użyć, tak długo, jak nie spodziewasz się zmiany, który przedmiot wskazuje na:

Na przykład,

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

A teraz możemy użyć zmiennej globalnej:

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

Modyfikacja zmiennej globalnej z wnętrza funkcji

Aby wskazać zmienną globalną w innym obiekcie, musisz ponownie użyć słowa kluczowego globalnego:

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

Zauważ, że po napisaniu tej funkcji kod faktycznie zmieniający go nadal nie działa:

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

Więc po wywołaniu funkcji:

>>> change_global_variable()

Widzimy, że zmienna globalna została zmieniona. Nazwa global_variable wskazuje teraz do 'Bar':

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

Zauważ, że "globalny" w Pythonie nie jest naprawdę globalny - jest to tylko globalny na poziomie modułu. Dostępne jest więc tylko funkcje napisane w modułach, w których jest globalny. Funkcje Pamiętaj, że moduł, w którym są zapisywane, więc gdy są eksportowane do innych modułów, nadal wyglądają w module, w którym zostały stworzone, aby znaleźć zmienne globalne.

Zmienne lokalne o tej samej nazwie

Jeśli utworzysz zmienną lokalną o tej samej nazwie, przekaże zmienną globalną:

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!!!'

Jednak korzystanie z tej misję zmiennej lokalnej nie zmienia zmiennej globalnej:

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

Należy pamiętać, że należy unikać korzystania z zmiennych lokalnych o tych samych nazwach jako globals, chyba że wiesz dokładnie, co robisz i masz bardzo dobry powód do tego. Nie spotkałem jeszcze takiego powodu.

Otrzymujemy takie samo zachowanie w klasach

Prosi się o komentarz:

Co zrobić, jeśli chcę utworzyć zmienną globalną w funkcji wewnątrz klasy i chcesz użyć tej zmiennej w innej funkcji wewnątrz innej klasy?

Tutaj pokazuję, że otrzymujemy takie samo zachowanie w metodach, jak w regularnych funkcjach:

class Foo:
    def foo(self):
        global global_variable
        global_variable = 'Foo'

class Bar:
    def bar(self):
        return global_variable + '!!!'

Foo().foo()

I teraz:

>>> Bar().bar()
'Foo!!!'

Ale sugerowałbym zamiast używać zmiennych globalnych używasz atrybutów klasy, aby uniknąć zaśmiecania przestrzeni nazw modułu. Należy również pamiętać, że nie używamy {{ X0 }} argumenty tutaj - mogą to być metody klasy (przydatne jeśli mutacji atrybutu class od zwykłego {{ }} argumentu X1 ) lub metody statyczne ( nie self lub { { X3}}).

58
Aaron Hall 19 styczeń 2020, 14:41

Dzięki równoległym wykonaniu zmienne globalne mogą powodować nieoczekiwane wyniki, jeśli nie rozumiesz, co się dzieje. Oto przykład korzystania z zmiennej globalnej w ramach wieloprocesowych. Widzimy wyraźnie, że każdy proces działa z własną kopią zmiennej:

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))

Wynik:

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]
36
Rob Bednark 3 styczeń 2017, 02:34

Jak okaże się, odpowiedź jest zawsze prosta.

Oto mały moduł próbki z prostym sposobem, aby pokazać go w definicji main:

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

def isTheNumber():
    return helper

Oto jak pokazać go w definicji main:

import TestPy

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

if __name__ == '__main__':
    main()

Ten prosty kod działa tak samo, a to będzie wykonywać. Mam nadzieję, że to pomoże.

27
AEF 28 wrzesień 2018, 11:34

Tym, co mówisz, jest użycie takiego sposobu:

globvar = 5

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

f()  # Prints 5

Ale lepszym sposobem jest użycie w takiej zmiennej globalnej:

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

Oba dają ten sam produkt.

26
funie200 1 grudzień 2020, 07:45

Musisz odwołać się do zmiennej globalnej w każdej funkcji, której chcesz użyć.

Następująco:

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]
"""
23
Peter Mortensen 4 luty 2015, 18:45

W rzeczywistości nie przechowujesz globalnych w zmiennej lokalnej, wystarczy tworzyć lokalne odniesienie do tego samego obiektu, do którego odnosi się oryginalne globalne odniesienie do. Pamiętaj, że prawie wszystko w Pythonie jest nazwą odnoszącą się do obiektu i nic nie zostanie skopiowane w zwykłej operacji.

Jeśli nie musiałeś wyraźnie określić, gdy identyfikator miał odnosić się do predefiniowanego globalnego, a następnie prawdopodobnie trzeba wyraźnie określić, gdy identyfikator jest nową zmienną lokalną (na przykład, z czymś takim jak polecenie "var" widziane w javascript). Ponieważ zmienne lokalne są bardziej powszechne niż zmienne globalne w żadnym poważnym i nietrywialnym systemie, system Pythona ma więcej sensu w większości przypadków.

Możesz , możesz mieć język, który próbował odgadnąć, używając zmiennej globalnej, gdyby istniała lub tworzy zmienną lokalną, jeśli nie. Jednak byłoby to bardzo podatne na błędy. Na przykład importowanie innego modułu można przypadkowo wprowadzić zmienną globalną przez tę nazwę, zmieniając zachowanie programu.

22
Peter Mortensen 30 maj 2011, 21:09

Spróbuj tego:

def x1():
    global x
    x = 6

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

x = 5
x1()
x2()  # output --> 7
20
not2qubit 27 listopad 2020, 17:41

W przypadku, gdy masz zmienną lokalną o tej samej nazwie, możesz użyć { {X0}} Funkcja.

globals()['your_global_var'] = 42
16
Martin Thoma 7 kwiecień 2017, 19:15

Następujący i jako dodatek, użyj pliku do zawierania wszystkich zmiennych globalnych, które zostały zadeklarowane lokalnie, a następnie {x0}}:

Plik initval.py :

Stocksin = 300
Prices = []

Plik getstocks.py :

import initval as iv

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


def getmycharts():
    for ic in range(iv.Stocksin):
14
Georgy 21 maj 2019, 10:59

Pisanie do wyraźnych elementów globalnej tablicy nie jest najwyraźniej potrzebować globalnej deklaracji, choć pisanie do tego "Hurtownie" ma to wymaganie:

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
13
Mike Lampton 8 styczeń 2016, 22:35

Odniesienie do przestrzeni nazw klasy, w której chcesz zmienić pojawienie się.

W tym przykładzie Runner używa max z konfiguracji pliku. Chcę, aby mój test zmienić wartość max , gdy biegacz używa go.

main / config.py

max = 15000

main / runner.py

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

testy / 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()
7
llewellyn falco 19 sierpień 2017, 08:48