Pertanyaan Menggunakan variabel global dalam suatu fungsi


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

Jika saya membuat variabel global dalam satu fungsi, bagaimana saya bisa menggunakan variabel global itu dalam fungsi lain? Apakah saya perlu menyimpan variabel global dalam variabel lokal dari fungsi yang membutuhkan aksesnya?


2466
2018-01-08 05:45


asal


Jawaban:


Anda dapat menggunakan variabel global dalam fungsi lain dengan mendeklarasikannya sebagai global di setiap fungsi yang ditetapkan 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 alasannya adalah karena variabel global sangat berbahaya, Python ingin memastikan bahwa Anda benar-benar tahu bahwa itulah yang Anda mainkan dengan secara eksplisit mengharuskan global kata kunci.

Lihat jawaban lain jika Anda ingin berbagi variabel global di seluruh modul.


3497
2018-01-08 08:39



Jika saya memahami situasi Anda dengan benar, apa yang Anda lihat adalah hasil dari bagaimana Python menangani namespace lokal (fungsi) dan global (modul).

Katakanlah Anda 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, tetapi cetaknya 5. Seperti telah disebutkan, jika Anda menambahkan 'global'deklarasi untuk func1(), kemudian func2() akan mencetak 42.

def func1():
    global myGlobal
    myGlobal = 42

Apa yang terjadi di sini adalah bahwa Python menganggap bahwa nama apa pun itu ditugaskan untuk, di mana saja dalam suatu fungsi, bersifat lokal untuk fungsi itu kecuali secara eksplisit mengatakan sebaliknya. Jika hanya bacaan dari nama, dan nama itu tidak ada secara lokal, ia akan mencoba mencari nama dalam lingkup apa pun yang mengandung (mis. lingkup global modul).

Saat Anda menetapkan 42 nama myGlobalOleh karena itu, Python membuat variabel lokal yang membayangi variabel global dengan nama yang sama. Lokal itu keluar dari ruang lingkup dan sampah yang dikumpulkan kapan func1() kembali; sementara itu, func2() tidak pernah bisa melihat apa pun selain nama global (tidak dimodifikasi). Perhatikan bahwa keputusan namespace ini terjadi pada waktu kompilasi, bukan saat runtime - jika Anda membaca nilai myGlobal dalam func1() sebelum Anda menetapkannya, Anda akan mendapatkan UnboundLocalError, karena Python telah memutuskan bahwa itu harus menjadi variabel lokal tetapi belum memiliki nilai yang terkait dengannya. Tetapi dengan menggunakan 'global'Pernyataan, Anda memberi tahu Python bahwa itu harus mencari tempat lain untuk nama bukannya menugaskan ke lokal.

(Saya percaya bahwa perilaku ini sebagian besar berasal dari optimalisasi ruang nama lokal - tanpa perilaku ini, VM Python perlu melakukan setidaknya tiga pencarian nama setiap kali nama baru ditetapkan di dalam fungsi (untuk memastikan bahwa nama tidak t sudah ada pada level module / builtin), yang secara signifikan akan memperlambat operasi yang sangat umum.)


660
2018-01-08 09:19



Anda mungkin ingin menjelajahi gagasan ruang nama. Dengan Python, the modul adalah tempat alami untuk global data:

Setiap modul memiliki tabel simbol pribadi, yang digunakan sebagai tabel simbol global oleh semua fungsi yang didefinisikan dalam modul. Dengan demikian, penulis modul dapat menggunakan variabel global dalam modul tanpa mengkhawatirkan bentrokan yang tidak disengaja dengan variabel global pengguna. Di sisi lain, jika Anda tahu apa yang Anda lakukan, Anda dapat menyentuh variabel global modul dengan notasi yang sama yang digunakan untuk merujuk fungsinya, modname.itemname.

Penggunaan spesifik global-in-a-module dijelaskan di sini - how-do-i-share-global-variable-across-modules, dan untuk kelengkapan isinya dibagikan di sini:

Cara kanonik untuk berbagi informasi antar modul dalam satu program adalah dengan membuat modul konfigurasi khusus (sering disebut config atau cfg). Cukup impor modul konfigurasi di semua modul aplikasi Anda; modul kemudian menjadi tersedia sebagai nama global. Karena hanya ada satu contoh dari setiap modul, setiap perubahan yang dilakukan pada objek modul bisa tercermin di mana-mana. Sebagai contoh:

File: config.py

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

File: mod.py

import config
config.x = 1

File: main.py

import config
import mod
print config.x

175
2018-01-08 05:59



Python menggunakan heuristik sederhana untuk menentukan ruang lingkup mana yang harus memuat variabel dari, antara lokal dan global. Jika nama variabel muncul di sisi kiri penugasan, tetapi tidak dinyatakan global, diasumsikan sebagai lokal. Jika tidak muncul di sisi kiri penugasan, diasumsikan bersifat 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        
>>> 

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


75
2017-07-12 12:35



Jika Anda ingin merujuk ke variabel global dalam suatu fungsi, Anda dapat menggunakan global kata kunci untuk menyatakan variabel mana yang bersifat global. Anda tidak harus menggunakannya dalam semua kasus (karena seseorang di sini salah mengklaim) - jika nama yang direferensikan dalam ekspresi tidak dapat ditemukan dalam lingkup lokal atau cakupan dalam fungsi-fungsi di mana fungsi ini didefinisikan, itu dicari di antara global variabel.

Namun, jika Anda menetapkan ke variabel baru yang tidak dideklarasikan sebagai global dalam fungsi, secara implisit dinyatakan sebagai lokal, dan dapat membayangi setiap variabel global yang ada dengan nama yang sama.

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


47
2018-01-08 09:03



Selain jawaban yang sudah ada dan membuat ini lebih membingungkan:

Dalam Python, variabel yang hanya dirujuk di dalam fungsi adalah    secara implisit global. Jika suatu variabel diberi nilai baru di mana saja   dalam tubuh fungsi, itu diasumsikan sebagai a lokal. Jika suatu variabel   pernah diberi nilai baru di dalam fungsi, variabel tersebut   secara implisit lokal, dan Anda perlu secara eksplisit mendeklarasikannya sebagai 'global'.

Meskipun sedikit mengejutkan pada awalnya, pertimbangan momen menjelaskan   ini. Di satu sisi, membutuhkan global untuk variabel yang ditetapkan menyediakan a   melawan efek samping yang tidak diinginkan. Di sisi lain, jika global   diperlukan untuk semua referensi global, Anda akan menggunakan global semua   waktu. Anda harus menyatakan sebagai global setiap referensi ke bawaan   berfungsi atau ke komponen modul yang diimpor. Kekacauan ini akan   mengalahkan kegunaan deklarasi global untuk mengidentifikasi   efek samping.

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


36
2017-07-04 10:23



Jika saya membuat variabel global dalam satu fungsi, bagaimana saya bisa menggunakan variabel itu di 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 sebenarnya tidak menjalankan kodenya. Jadi kami menyebutnya create_global_variable fungsi:

>>> create_global_variable()

Menggunakan globals tanpa modifikasi

Anda bisa menggunakannya, selama Anda tidak berharap untuk mengubah objek mana yang ditunjuknya:

Sebagai contoh,

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

dan sekarang kita bisa menggunakan variabel global:

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

Modifikasi variabel global dari dalam fungsi

Untuk mengarahkan variabel global pada objek yang berbeda, Anda diminta untuk menggunakan kata kunci global lagi:

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

Perhatikan bahwa setelah menulis fungsi ini, kode yang benar-benar mengubahnya masih belum berjalan:

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

Jadi setelah memanggil fungsi:

>>> change_global_variable()

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

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

Perhatikan bahwa "global" dalam Python tidak benar-benar global - itu hanya global ke level modul. Jadi hanya tersedia untuk fungsi yang ditulis dalam modul yang bersifat global. Fungsi ingat modul di mana mereka ditulis, jadi ketika mereka diekspor ke modul lain, mereka masih melihat di 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 menutupi 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!!!'

Tetapi menggunakan variabel lokal yang salah nama itu tidak mengubah variabel global:

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

Perhatikan bahwa Anda harus menghindari menggunakan variabel lokal dengan nama yang sama dengan global kecuali Anda tahu persis apa yang Anda lakukan dan memiliki alasan yang sangat bagus untuk melakukannya. Saya belum menemukan alasan seperti itu.


31
2018-01-01 19:55



Dengan eksekusi paralel, variabel global dapat menyebabkan hasil yang tidak terduga jika Anda tidak mengerti apa yang terjadi. Berikut ini contoh penggunaan variabel global dalam multiprocessing. Kita dapat dengan jelas melihat bahwa setiap proses bekerja dengan salinan variabelnya sendiri:

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

Keluaran:

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]

28
2017-10-03 05:41



Anda perlu mereferensikan variabel global di 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]
"""

19
2017-12-20 12:45



Apa yang Anda katakan adalah menggunakan metode seperti ini:

globvar = 5

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

f()  # Prints 5

Tetapi cara yang lebih baik adalah menggunakan variabel global seperti ini:

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

Keduanya memberikan hasil yang sama.


19
2017-12-04 06:27