Menggunakan variabel global dalam fungsi

Bagaimana saya bisa membuat atau menggunakan global variabel dalam sebuah fungsi?

Jika saya membuat sebuah variabel global dalam satu fungsi, bagaimana saya bisa menggunakan global variable dalam fungsi lain? Apakah saya perlu untuk menyimpan variabel global dalam variabel lokal dari fungsi yang membutuhkan akses?

Larutan

Anda dapat menggunakan variabel global dalam fungsi-fungsi lain dengan menyatakan itu sebagai global di masing-masing fungsi yang ditunjuk untuk itu:

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

Saya membayangkan alasan untuk ini adalah bahwa, sejak variabel global yang sangat berbahaya, Python ingin memastikan bahwa anda benar-benar tahu bahwa's apa yang anda're bermain dengan dengan secara eksplisit mewajibkan global kata kunci.

Melihat jawaban yang lain jika anda ingin berbagi variabel global seluruh modul.

Komentar (13)

Jika saya'm memahami situasi anda dengan benar, apa yang anda're lihat adalah hasil dari bagaimana Python menangani lokal (fungsi) dan global (modul) namespaces.

Katakanlah anda've punya modul seperti ini:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Anda mungkin mengharapkan ini untuk mencetak 42, tapi bukannya mencetak 5. Seperti telah disebutkan di atas, jika anda menambahkan 'global' deklarasi untuk func1(), kemudian func2() akan mencetak 42.

def func1():
    global myGlobal
    myGlobal = 42

Apa's terjadi di sini adalah bahwa Python mengasumsikan bahwa setiap nama yang diberikan ke, di mana saja di dalam sebuah fungsi, adalah lokal untuk fungsi itu kecuali secara eksplisit mengatakan sebaliknya. Jika itu adalah hanya membaca dari sebuah nama, dan nama itu doesn't ada secara lokal, itu akan mencoba untuk mencari nama di setiap mengandung lingkup (misalnya, modul's lingkup global).

Ketika anda menetapkan 42 nama myGlobal, oleh karena itu, Python menciptakan variabel lokal bahwa bayangan global variabel dengan nama yang sama. Yang lokal keluar dari ruang lingkup dan mengumpulkan sampah ketika func1() kembali; sementara itu, func2() tidak akan pernah bisa melihat apa-apa selain dari (dimodifikasi) nama global. Catatan bahwa ini namespace keputusan yang terjadi pada waktu kompilasi, tidak pada saat runtime-jika anda adalah untuk membaca nilai dari myGlobal dalam func1() sebelum anda menetapkan untuk itu, anda'a mendapatkan UnboundLocalError, karena Python telah memutuskan bahwa itu harus menjadi variabel lokal tetapi tidak memiliki nilai apapun yang terkait dengan itu belum. Tapi dengan menggunakan 'global' pernyataan, anda memberitahu Python itu harus mencari tempat lain untuk nama bukan untuk menetapkan secara lokal.

(Aku percaya bahwa perilaku ini berasal sebagian besar melalui optimalisasi lokal namespaces-tanpa perilaku ini, Python's VM akan perlu untuk melakukan setidaknya tiga nama lookup setiap kali nama baru ditugaskan ke dalam sebuah fungsi (untuk memastikan bahwa nama didn't sudah ada di modul/builtin tingkat), yang secara signifikan akan memperlambat sangat umum operasi.)

Komentar (4)

Anda mungkin ingin mengeksplorasi gagasan nama. Di Python, yang modul adalah tempat alami untuk global data:

masing-Masing modul memiliki sendiri pribadi tabel simbol, yang digunakan sebagai simbol global meja dengan semua fungsi yang ditetapkan dalam modul. Dengan demikian, penulis modul dapat menggunakan variabel global dalam modul tanpa khawatir tentang kecelakaan bentrokan dengan pengguna global variabel. Di sisi lain, jika anda tahu apa yang anda lakukan anda dapat menyentuh modul variabel global dengan notasi yang digunakan untuk merujuk kepada fungsi-fungsinya, modname.itemname.

Tertentu menggunakan global-in-a-modul ini dijelaskan di sini - Bagaimana cara berbagi variabel global seluruh modul?, dan untuk kelengkapan isi dibagi di sini:

kanonik cara untuk berbagi informasi seluruh modul dalam satu program ini adalah untuk membuat suatu konfigurasi khusus modul (sering disebut config atau cfg). Hanya mengimpor modul konfigurasi di semua modul aplikasi anda; modul kemudian menjadi tersedia sebagai nama global. Karena hanya ada satu contoh dari masing-masing modul, setiap perubahan yang dibuat untuk modul objek mendapatkan tercermin di mana-mana. Misalnya:

File: config.py

x = 0 # Default nilai dari 'x' pengaturan konfigurasi

File: mod.py

impor config config.x = 1

File: main.py

impor config impor mod cetak config.x

Komentar (2)

Python menggunakan sederhana heuristik untuk menentukan ruang lingkup ini harus memuat variabel dari, antara lokal dan global. Jika nama variabel yang muncul di sisi kiri dari sebuah tugas, tapi tidak dideklarasikan secara global, hal ini diasumsikan lokal. Jika tidak muncul di sisi kiri dari sebuah tugas, hal ini diasumsikan untuk menjadi 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        
>>> 

Melihat bagaimana baz, yang muncul di sisi kiri dari tugas di foo(), adalah satu-satunya LOAD_FAST variabel.

Komentar (1)

Jika anda ingin merujuk ke variabel global dalam fungsi, anda dapat menggunakan global kata kunci untuk mendeklarasikan variabel yang global. Anda don't harus menggunakannya dalam semua kasus (seperti seseorang di sini salah klaim) - jika nama yang direferensikan dalam sebuah ekspresi yang tidak dapat ditemukan di daerah lingkup atau cakupan dalam fungsi-fungsi di mana fungsi ini didefinisikan, hal ini tampak antara variabel global.

Namun, jika anda menetapkan ke new variabel tidak dideklarasikan sebagai global dalam fungsi, hal ini secara implisit dinyatakan sebagai lokal, dan dapat menaungi setiap ada global variabel dengan nama yang sama.

Juga, global variabel yang berguna, yang bertentangan dengan beberapa OOP fanatik yang mengklaim sebaliknya, terutama untuk script kecil, di mana OOP adalah berlebihan.

Komentar (1)

Di samping sudah ada jawaban dan untuk membuat ini lebih membingungkan:

Di Python, variabel-variabel yang hanya dapat dirujuk di dalam fungsi secara implisit global. Jika variabel ini diberi nilai baru di mana saja dalam fungsi tubuh, itu diasumsikan untuk menjadi lokal. Jika variabel yang pernah ditugaskan nilai baru di dalam fungsi tersebut, variabel secara implisit lokal, dan anda harus secara eksplisit menyatakan hal itu sebagai 'global'.

Meskipun sedikit mengejutkan pada awalnya, saat itu pertimbangan menjelaskan ini. Di satu sisi, membutuhkan global untuk ditugaskan variabel yang menyediakan bar terhadap yang tidak diinginkan efek samping. Di sisi lain, jika global diperlukan untuk semua referensi global, anda akan menggunakan global semua waktu. Anda akan memiliki untuk menyatakan sebagai global setiap referensi untuk sebuah built-in fungsi atau komponen yang diimpor modul. Kekacauan ini akan mengalahkan kegunaan dari deklarasi global untuk mengidentifikasi efek samping.

Sumber: Apa aturan untuk lokal dan global variabel dalam Python?.

Komentar (0)

Jika saya membuat sebuah variabel global dalam satu fungsi, bagaimana saya bisa menggunakan variabel dalam fungsi lain?

Kita dapat membuat global dengan fungsi berikut:

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' 

Menulis fungsi yang tidak benar-benar menjalankan kode. Jadi kita sebut create_global_variable fungsi:

>>> create_global_variable()

Menggunakan globals tanpa modifikasi

Anda hanya bisa menggunakannya, asalkan anda don't berharap untuk mengubah objek yang menunjuk ke:

Misalnya,

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

dan sekarang kita dapat menggunakan variabel global:

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

Modifikasi variabel global dari dalam fungsi

Untuk titik variabel global pada objek yang berbeda, anda diwajibkan untuk menggunakan global kata kunci lagi:

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

Perhatikan bahwa setelah menulis fungsi ini, kode benar-benar mengubah hal itu masih belum berjalan:

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

Jadi setelah memanggil fungsi:

>>> change_global_variable()

kita bisa melihat bahwa variabel global telah berubah. The global_variable nama sekarang menunjuk ke 'Bar':

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

Perhatikan bahwa "global" dalam Python adalah tidak benar-benar global - it's hanya global ke tingkat modul. Jadi hal ini hanya tersedia untuk fungsi-fungsi yang ditulis dalam modul-modul yang lebih global. Fungsi mengingat modul di mana mereka ditulis, jadi ketika mereka yang diekspor ke modul lain, mereka masih terlihat dalam modul di mana mereka diciptakan untuk menemukan variabel global.

Variabel lokal dengan nama yang sama

Jika anda membuat variabel lokal dengan nama yang sama, itu akan menaungi variabel 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!!!'

Tapi menggunakan yang misnamed variabel lokal tidak mengubah variabel global:

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

Perhatikan bahwa anda harus menghindari menggunakan variabel lokal dengan nama yang sama seperti globals kecuali anda tahu persis apa yang anda lakukan dan memiliki alasan yang sangat baik untuk melakukannya. Saya belum pernah menjumpai alasan seperti itu.

Komentar (0)

Dengan eksekusi paralel, variabel global dapat menyebabkan hasil yang tak terduga jika anda don't memahami apa yang terjadi. Berikut adalah contoh penggunaan variabel global dalam multiprocessing. Kita dapat dengan jelas melihat bahwa masing-masing proses bekerja dengan copy dari variabel:

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]
Komentar (0)

Ternyata jawabannya adalah selalu sederhana.

Berikut ini adalah contoh kecil modul dengan cara yang mudah untuk menunjukkan hal ini dalam utama definisi:

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

def isTheNumber():
    return helper

Berikut ini adalah cara untuk menunjukkan hal ini dalam utama definisi:

import TestPy

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

if __name__ == '__main__':
    main()

Ini kode sederhana bekerja hanya seperti itu, dan itu akan mengeksekusi. Saya harap ini membantu.

Komentar (3)

Apa yang anda katakan adalah dengan menggunakan metode seperti ini:

globvar = 5

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

f()  # Prints 5

Tapi cara yang lebih baik adalah dengan menggunakan variabel global seperti ini:

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

Keduanya memberikan output yang sama.

Komentar (0)

Anda perlu referensi variabel global dalam setiap fungsi yang ingin anda gunakan.

Sebagai berikut:

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]
"""
Komentar (1)

Anda're tidak benar-benar menyimpan global variabel lokal, hanya menciptakan lokal referensi ke objek yang sama yang asli global mengacu pada. Ingat bahwa segala sesuatu cukup banyak di Python adalah sebuah nama yang mengacu pada suatu objek, dan tidak ada yang akan disalin dalam operasi yang biasa.

Jika anda didn't harus secara eksplisit menentukan ketika sebuah identifier untuk merujuk ke standar global, maka anda'd mungkin harus secara eksplisit menentukan ketika sebuah identifier adalah variabel lokal baru bukan (misalnya, dengan sesuatu seperti 'var' perintah yang terlihat dalam JavaScript). Karena variabel lokal adalah lebih umum daripada variabel global di setiap masalah yang serius dan non-sepele sistem, Python's sistem yang lebih masuk akal dalam kebanyakan kasus.

Anda bisa memiliki bahasa yang berusaha untuk menebak, menggunakan variabel global jika itu ada atau membuat variabel lokal jika tidak't. Namun, itu akan menjadi sangat rawan kesalahan. Misalnya, mengimpor modul lain bisa secara tidak sengaja memperkenalkan variabel global dengan nama itu, mengubah perilaku dari program anda.

Komentar (0)

Coba ini:

def x1():
    global x
    x = 6

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

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

Dalam kasus anda memiliki variabel lokal dengan nama yang sama, anda mungkin ingin menggunakan globals() fungsi.

globals()['your_global_var'] = 42
Komentar (0)

Berikut di dan sebagai add on, menggunakan sebuah file yang berisi semua variabel global semua dinyatakan secara lokal dan kemudian mengimpor:

File initval.py:

Stocksin = 300
Prices = []

File getstocks.py:

import initval as iv

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

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

Menulis untuk unsur eksplisit global array tidak tampaknya perlu deklarasi global, meskipun menulis itu "grosir" tidak memiliki persyaratan:

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
Komentar (0)

I'm menambahkan ini karena saya belum't melihat hal itu di setiap jawaban yang lain dan mungkin akan berguna bagi seseorang yang bergumul dengan sesuatu yang serupa. The globals() fungsi mengembalikan mutable global simbol kamus mana anda dapat "ajaib" membuat data yang tersedia untuk sisa dari kode anda. Misalnya:

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

dan

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

Hanya akan membiarkan anda dump/memuat variabel-variabel yang keluar dari dan ke global namespace. Super nyaman, tidak ada pertengkaran, tidak ada ribut-ribut. Cukup yakin itu's Python 3 saja.

Komentar (1)

Referensi kelas namespace di mana anda ingin mengubah muncul.

Dalam contoh ini, pelari menggunakan max dari file config. Saya ingin saya tes untuk mengubah nilai max ketika pelari yang menggunakannya.

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                # 
Komentar (0)