Menggunakan variabel global dalam suatu fungsi

3115

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 di fungsi lain? Apakah saya perlu menyimpan variabel global dalam variabel lokal dari fungsi yang memerlukan aksesnya?

pengguna46646
sumber

Jawaban:

4248

Anda bisa menggunakan variabel global dalam fungsi lain dengan mendeklarasikannya seperti globalpada setiap fungsi yang ditugaskan padanya:

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 apa yang Anda mainkan dengan meminta globalkata kunci secara eksplisit .

Lihat jawaban lain jika Anda ingin membagikan variabel global lintas modul.

Paul Stephenson
sumber
838
Terlalu berlebihan untuk menyebut global sebagai "sangat berbahaya." Global sangat baik dalam setiap bahasa yang pernah ada dan pernah ada. Mereka memiliki tempat mereka. Apa yang seharusnya Anda katakan adalah mereka dapat menyebabkan masalah jika Anda tidak tahu bagaimana memprogram.
Anthony
207
Saya pikir mereka cukup berbahaya. Namun dalam variabel python "global" sebenarnya modul-level, yang memecahkan banyak masalah.
Fábio Santos
246
Saya tidak setuju bahwa alasan Python memerlukan globalkata kunci adalah karena global berbahaya. Sebaliknya, itu karena bahasa tidak mengharuskan Anda untuk secara eksplisit mendeklarasikan variabel dan secara otomatis mengasumsikan bahwa variabel yang Anda tetapkan memiliki ruang lingkup fungsi kecuali Anda memberi tahu sebaliknya. Kata globalkunci adalah cara yang disediakan untuk mengatakan sebaliknya.
Nate CK
7
@avgvstvs: Dan jika Anda menerapkan program yang sama tanpa global, Anda masih memiliki jumlah jalur kode yang sama. Argumen yang Anda buat bukanlah argumen menentang global.
Lightness Races dalam Orbit
13
@LightnessRacesinOrbit Saya tidak mengerti maksud Anda. Jika Anda menghapus variabel global, Anda menghapus faktor yang mempersulit sekarang, fungsi sewenang-wenang tidak dapat lagi mengubah status program , di berbagai titik dalam eksekusi - sehingga mengubah eksekusi dengan cara yang tidak terlihat oleh fungsi lain yang bergantung pada variabel itu. Anda tidak lagi harus melacak, "Apakah f2()mengubah status jadi sekarang f3()mungkin melakukan sesuatu yang tidak terduga? Sekarang fungsi dapat beroperasi agnostik ke status program eksternal.
avgvstvs
775

Jika saya memahami situasi Anda dengan benar, apa yang Anda lihat adalah hasil dari bagaimana Python menangani ruang nama 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 mencetak 42, tetapi malah mencetak 5. Seperti yang telah disebutkan, jika Anda menambahkan globaldeklarasi ' ' func1(), maka func2()akan mencetak 42.

def func1():
    global myGlobal
    myGlobal = 42

Apa yang terjadi di sini adalah bahwa Python mengasumsikan bahwa setiap nama yang ditugaskan , di mana saja dalam suatu fungsi, adalah lokal untuk fungsi itu kecuali secara eksplisit mengatakan sebaliknya. Jika hanya membaca dari suatu nama, dan nama itu tidak ada secara lokal, ia akan mencoba mencari nama dalam lingkup apa pun yang berisi (misalnya cakupan global modul).

myGlobalOleh karena itu, ketika Anda menetapkan 42 untuk nama , Python membuat variabel lokal yang membayangi variabel global dari nama yang sama. Lokal itu keluar dari ruang lingkup dan dikumpulkan ketika func1()kembali; sementara itu, func2()tidak pernah dapat melihat apa pun selain nama global (yang tidak dimodifikasi). Perhatikan bahwa keputusan namespace ini terjadi pada waktu kompilasi, bukan pada saat runtime - jika Anda membaca nilai myGlobaldi dalam func1()sebelum Anda menetapkannya, Anda akan mendapatkan UnboundLocalError, karena Python telah memutuskan bahwa itu harus merupakan variabel lokal tetapi belum memiliki nilai apa pun yang terkait dengannya. Tetapi dengan menggunakan pernyataan ' global', Anda memberi tahu Python bahwa itu harus mencari di tempat lain untuk nama alih-alih menetapkan secara 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 ditugaskan di dalam suatu fungsi (untuk memastikan bahwa nama itu tidak ' t sudah ada pada tingkat modul / builtin), yang secara signifikan akan memperlambat operasi yang sangat umum.)

Jeff Shannon
sumber
Anda menyebutkan bahwa keputusan namespace terjadi pada waktu kompilasi , saya rasa itu tidak benar. dari apa yang saya pelajari kompilasi python hanya memeriksa kesalahan sintaks, bukan kesalahan nama coba contoh ini def A (): x + = 1 , jika Anda tidak menjalankannya, itu tidak akan memberikan UnboundLocalError , harap verifikasi terima kasih
watashiSHUN
1
Adalah umum untuk menggunakan huruf kapital untuk variabel global sepertiMyGlobal = 5
Vassilis
3
@watashiSHUN: Keputusan namespace tidak terjadi pada waktu kompilasi. Memutuskan bahwa xitu lokal berbeda dari memeriksa saat runtime jika nama lokal terikat ke nilai sebelum digunakan pertama kali.
BlackJack
9
@Vassilis: Hal ini umum untuk kasus atas semua huruf: MY_GLOBAL = 5. Lihat Panduan Gaya untuk Kode Python .
BlackJack
223

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

Setiap modul memiliki tabel simbol pribadi sendiri, yang digunakan sebagai tabel simbol global oleh semua fungsi yang didefinisikan dalam modul. Dengan demikian, penulis modul dapat menggunakan variabel global dalam modul tanpa khawatir tentang bentrokan 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 ke fungsinya modname.itemname,.

Penggunaan spesifik global-in-a-module dijelaskan di sini - Bagaimana cara saya membagikan variabel global di seluruh modul? , dan untuk kelengkapan isinya dibagikan di sini:

Cara kanonik untuk berbagi informasi lintas modul dalam satu program adalah membuat modul konfigurasi khusus (sering disebut config atau cfg ). Impor saja modul konfigurasi di semua modul aplikasi Anda; modul kemudian tersedia sebagai nama global. Karena hanya ada satu instance dari setiap modul, setiap perubahan yang dilakukan pada objek modul 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
Gimel
sumber
1
karena suatu alasan saya tidak suka config.x bisakah saya menyingkirkannya? Saya datang dengan x = lambda: config.xdan kemudian saya memiliki nilai baru di x(). untuk beberapa alasan, memiliki a = config.xtidak melakukan trik untukku.
vladosaurus
3
@vladosaurus tidak from config import xmenyelesaikannya?
jhylands
93

Python menggunakan heuristik sederhana untuk memutuskan ruang lingkup mana yang harus memuat variabel dari, antara lokal dan global. Jika nama variabel muncul di sisi kiri penugasan, tetapi tidak dinyatakan global, itu dianggap lokal. Jika tidak muncul di sisi kiri penugasan, itu dianggap 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 penugasan foo(), adalah satu-satunya LOAD_FASTvariabel.

SingleNegationElimination
sumber
12
Heuristik mencari operasi yang mengikat . Penugasan adalah satu operasi seperti itu, mengimpor yang lain. Tetapi target forloop dan nama setelah asdalam withdan exceptpernyataan juga terikat.
Martijn Pieters
@ MartijnPieters Untuk nama setelah asdalam exceptklausa ini tidak jelas bagi saya. Tapi itu dihapus secara otomatis untuk menghemat memori.
Robert
1
@ Robert: bukan untuk menghemat memori, tetapi untuk menghindari membuat referensi melingkar, yang dapat menyebabkan kebocoran memori. Itu karena pengecualian merujuk traceback, dan traceback merujuk setiap namespace lokal dan global di seluruh tumpukan panggilan, termasuk as ...target dalam penangan pengecualian.
Martijn Pieters
62

Jika Anda ingin merujuk ke variabel global dalam suatu fungsi, Anda dapat menggunakan kata kunci global untuk mendeklarasikan variabel mana yang bersifat global. Anda tidak harus menggunakannya dalam semua kasus (seperti yang diklaim oleh seseorang di sini secara salah) - jika nama yang dirujuk dalam ekspresi tidak dapat ditemukan dalam lingkup lokal atau cakupan pada fungsi-fungsi di mana fungsi ini didefinisikan, itu terlihat di antara global variabel.

Namun, jika Anda menetapkan ke variabel baru yang tidak dideklarasikan sebagai global dalam fungsi, itu secara implisit dinyatakan sebagai lokal, dan itu dapat menaungi 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 berlebihan.

JS
sumber
Benar-benar kembali. fanatik. Sebagian besar pengguna Python menggunakannya untuk skrip dan membuat fungsi-fungsi kecil untuk memisahkan potongan-potongan kecil kode.
Paul Uszak
51

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

Kami 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 memanggil create_global_variablefungsi:

>>> create_global_variable()

Menggunakan global tanpa modifikasi

Anda bisa menggunakannya, selama Anda tidak berharap untuk mengubah objek 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 suatu fungsi

Untuk mengarahkan variabel global ke objek yang berbeda, Anda harus menggunakan kata kunci global lagi:

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

Perhatikan bahwa setelah menulis fungsi ini, kode sebenarnya mengubahnya masih belum berjalan:

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

Jadi setelah memanggil fungsi:

>>> change_global_variable()

kita dapat melihat bahwa variabel global telah diubah. The global_variablenama sekarang menunjuk ke 'Bar':

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

Perhatikan bahwa "global" dalam Python tidak benar-benar global - hanya global ke tingkat modul. Jadi ini hanya tersedia untuk fungsi-fungsi yang ditulis dalam modul di mana ia bersifat global. Fungsi mengingat modul di mana mereka ditulis, jadi ketika mereka diekspor ke modul lain, mereka masih mencari di modul di mana mereka dibuat 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!!!'

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 baik untuk melakukannya. Saya belum menemukan alasan seperti itu.

Kami mendapatkan perilaku yang sama di kelas

Sebuah tindak pada komentar bertanya:

apa yang harus dilakukan jika saya ingin membuat variabel global di dalam fungsi di dalam kelas dan ingin menggunakan variabel itu di dalam fungsi lain di dalam kelas lain?

Di sini saya menunjukkan kita mendapatkan perilaku yang sama dalam metode seperti yang kita lakukan dalam fungsi reguler:

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

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

Foo().foo()

Dan sekarang:

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

Tapi saya sarankan daripada menggunakan variabel global Anda menggunakan atribut kelas, untuk menghindari kekacauan namespace modul. Perhatikan juga, kami tidak menggunakan selfargumen di sini - ini bisa berupa metode kelas (berguna jika mengubah atribut kelas dari clsargumen biasa ) atau metode statis (tidak selfatau cls).

Aaron Hall
sumber
Keren, tetapi apa yang harus dilakukan jika saya ingin membuat variabel global di dalam fungsi di dalam kelas dan ingin menggunakan variabel itu di dalam fungsi lain di dalam kelas lain? Agak terjebak di sini
anonmanx
2
@anonmanx Saya tidak tahu mengapa Anda macet, itu perilaku yang sama dalam suatu metode seperti dalam fungsi biasa. Tapi saya akan memperbarui jawaban saya dengan komentar Anda dan beberapa kode demo, ok?
Aaron Hall
1
@anonmanx bagaimana itu?
Aaron Hall
OK saya mengerti. Jadi saya harus secara eksplisit memanggil fungsi itu untuk menggunakan variabel global itu.
anonmanx
47

Selain jawaban yang sudah ada dan untuk membuatnya lebih membingungkan:

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

Meskipun sedikit mengejutkan pada awalnya, pertimbangan sesaat menjelaskan hal ini. Di satu sisi, memerlukan global untuk variabel yang ditugaskan menyediakan bar terhadap efek samping yang tidak diinginkan. Di sisi lain, jika global diperlukan untuk semua referensi global, Anda akan menggunakan global setiap saat. Anda harus mendeklarasikan sebagai global setiap referensi ke fungsi bawaan 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 dalam Python? .

Rauni Lillemets
sumber
34

Dengan eksekusi paralel, variabel global dapat menyebabkan hasil yang tidak terduga jika Anda tidak mengerti apa yang sedang terjadi. Berikut adalah contoh penggunaan variabel global dalam proses multi. Kita dapat melihat dengan jelas 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]
Bohdan
sumber
25

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 dengan menggunakan variabel global seperti ini:

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

Keduanya memberikan output yang sama.

gxyd
sumber
25

Ternyata jawabannya selalu sederhana.

Berikut ini adalah contoh modul kecil dengan cara sederhana untuk menunjukkannya dalam maindefinisi:

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

def isTheNumber():
    return helper

Berikut ini cara menunjukkannya dalam maindefinisi:

import TestPy

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

if __name__ == '__main__':
    main()

Kode sederhana ini berfungsi begitu saja, dan itu akan dijalankan. Saya harap ini membantu.

pengguna2876408
sumber
1
terima kasih, saya baru mengenal python, tetapi tahu sedikit java. apa yang Anda katakan bekerja untuk saya. dan menulis global <ENTER> dalam kelas .. tampaknya lebih masuk akal bagi saya daripada dalam fungsi menulis 'global a' .. Saya perhatikan Anda tidak bisa mengatakan global a = 4
barlop
2
Ini mungkin trik python paling sederhana namun sangat berguna bagi saya. Saya menamai modul ini global_vars, dan menginisialisasi data init_global_vars, yang dipanggil dalam skrip startup. Kemudian, saya cukup membuat metode accessor untuk setiap var global yang ditentukan. Saya harap saya dapat memperbaiki ini beberapa kali! Peter terima kasih!
swdev
1
Bagaimana jika ada banyak banyak variabel global dan saya tidak mau harus menuliskannya satu per satu setelah pernyataan global?
jtlz2
23

Anda perlu referensi 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]
"""
Mohamed El-Saka
sumber
3
'di setiap fungsi yang ingin Anda gunakan' tidak benar, harus lebih dekat ke: 'di setiap fungsi di mana Anda ingin memperbarui '
spazm
21

Anda sebenarnya tidak menyimpan global dalam variabel lokal, hanya membuat referensi lokal ke objek yang sama dengan referensi global asli Anda. Ingat bahwa hampir semua yang ada di Python adalah nama yang merujuk ke objek, dan tidak ada yang disalin dalam operasi biasa.

Jika Anda tidak harus secara eksplisit menentukan kapan pengidentifikasi merujuk ke global yang telah ditentukan, maka Anda mungkin harus secara eksplisit menentukan kapan pengidentifikasi adalah variabel lokal baru sebagai gantinya (misalnya, dengan sesuatu seperti perintah 'var' terlihat di JavaScript). Karena variabel lokal lebih umum daripada variabel global dalam sistem serius dan non-sepele, sistem Python lebih masuk akal dalam banyak kasus.

Anda bisa memiliki bahasa yang mencoba menebak, menggunakan variabel global jika ada atau membuat variabel lokal jika tidak. Namun, itu akan sangat rawan kesalahan. Misalnya, mengimpor modul lain secara tidak sengaja dapat memperkenalkan variabel global dengan nama itu, mengubah perilaku program Anda.

Kylotan
sumber
17

Coba ini:

def x1():
    global x
    x = 6

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

x = 5
x1()
x2()  # output --> 7
Sagar Mehta
sumber
15

Jika Anda memiliki variabel lokal dengan nama yang sama, Anda mungkin ingin menggunakan globals()fungsinya .

globals()['your_global_var'] = 42
Martin Thoma
sumber
14

Setelah dan sebagai tambahan, gunakan file untuk memuat semua variabel global yang semuanya dideklarasikan secara lokal lalu import as:

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):
Georgy
sumber
1
Apa keuntungan memindahkan variabel global ke file lain? Apakah hanya untuk mengelompokkan variabel global dalam file kecil? Dan mengapa menggunakan pernyataan itu import ... as ...? Kenapa tidak adil import ...?
olibre
1
Ah ... Saya akhirnya mengerti keuntungannya: Tidak perlu menggunakan kata kunci global:-) => +1 :-) Harap edit jawaban Anda untuk menjelaskan interogasi yang mungkin dimiliki orang lain. Cheers
olibre
13

Menulis ke elemen eksplisit dari array global tampaknya tidak memerlukan deklarasi global, meskipun menulis kepadanya "grosir" memang 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
Mike Lampton
sumber
7

Saya menambahkan ini karena saya belum melihatnya di salah satu jawaban lain dan mungkin berguna bagi seseorang yang berjuang dengan sesuatu yang serupa. The globals()mengembalikan fungsi bisa berubah simbol global kamus mana Anda dapat "ajaib" Data make tersedia untuk sisa kode Anda. Sebagai contoh:

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 membuang / memuat variabel dari dan ke namespace global. Sangat nyaman, tidak ada masalah, tidak repot. Cukup yakin itu hanya Python 3.

Rafaël Dera
sumber
3
globals()selalu mengembalikan global yang tersedia dalam konteks lokal, jadi mutasi di sini mungkin tidak tercermin dalam modul lain.
Kiran Jonnalagadda
6

Referensi ruang nama kelas tempat Anda ingin perubahan muncul.

Dalam contoh ini, pelari menggunakan maks dari konfigurasi file. Saya ingin pengujian saya untuk mengubah nilai max ketika pelari menggunakannya.

main / config.py

max = 15000

main / runner.py

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

tes / 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()
llewellyn Falco
sumber
1

Global baik-baik saja - Kecuali dengan Multiprocessing

Global yang terkait dengan multi-pemrosesan pada berbagai platform / lingkungan seperti Windows / Mac OS di satu sisi dan Linux di sisi lain menyusahkan.

Saya akan menunjukkan ini kepada Anda dengan contoh sederhana yang menunjukkan masalah yang saya alami beberapa waktu lalu.

Jika Anda ingin memahami, mengapa hal-hal berbeda pada Windows / MacO dan Linux Anda perlu tahu itu, mekanisme default untuk memulai proses baru pada ...

  • Windows / MacO adalah 'spawn'
  • Linux adalah 'garpu'

Mereka berbeda dalam alokasi memori inisialisasi ... (tapi saya tidak membahas ini di sini).

Mari kita lihat masalah / contohnya ...

import multiprocessing

counter = 0

def do(task_id):
    global counter
    counter +=1
    print(f'task {task_id}: counter = {counter}')

if __name__ == '__main__':

    pool = multiprocessing.Pool(processes=4)
    task_ids = list(range(4))
    pool.map(do, task_ids)

Windows

Jika Anda menjalankan ini pada Windows (Dan saya kira pada MacOS juga), Anda mendapatkan output berikut ...

task 0: counter = 1
task 1: counter = 2
task 2: counter = 3
task 3: counter = 4

Linux

Jika Anda menjalankan ini di Linux, Anda mendapatkan yang berikut ini.

task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1
thomas
sumber