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?
python
global-variables
scope
pengguna46646
sumber
sumber
global
kata 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. Kataglobal
kunci adalah cara yang disediakan untuk mengatakan sebaliknya.f2()
mengubah status jadi sekarangf3()
mungkin melakukan sesuatu yang tidak terduga? Sekarang fungsi dapat beroperasi agnostik ke status program eksternal.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:
Anda mungkin mengharapkan ini mencetak 42, tetapi malah mencetak 5. Seperti yang telah disebutkan, jika Anda menambahkan
global
deklarasi ' 'func1()
, makafunc2()
akan mencetak 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).
myGlobal
Oleh 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 ketikafunc1()
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 nilaimyGlobal
di dalamfunc1()
sebelum Anda menetapkannya, Anda akan mendapatkanUnboundLocalError
, 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.)
sumber
MyGlobal = 5
x
itu lokal berbeda dari memeriksa saat runtime jika nama lokal terikat ke nilai sebelum digunakan pertama kali.MY_GLOBAL = 5
. Lihat Panduan Gaya untuk Kode Python .Anda mungkin ingin menjelajahi gagasan ruang nama . Dalam Python, modul adalah tempat alami untuk data global :
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:
sumber
config.x
bisakah saya menyingkirkannya? Saya datang denganx = lambda: config.x
dan kemudian saya memiliki nilai baru dix()
. untuk beberapa alasan, memilikia = config.x
tidak melakukan trik untukku.from config import x
menyelesaikannya?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.
Lihat bagaimana baz, yang muncul di sisi kiri penugasan
foo()
, adalah satu-satunyaLOAD_FAST
variabel.sumber
for
loop dan nama setelahas
dalamwith
danexcept
pernyataan juga terikat.as
dalamexcept
klausa ini tidak jelas bagi saya. Tapi itu dihapus secara otomatis untuk menghemat memori.as ...
target dalam penangan pengecualian.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.
sumber
Kami dapat membuat global dengan fungsi berikut:
Menulis fungsi sebenarnya tidak menjalankan kodenya. Jadi kami memanggil
create_global_variable
fungsi:Menggunakan global tanpa modifikasi
Anda bisa menggunakannya, selama Anda tidak berharap untuk mengubah objek yang ditunjuknya:
Sebagai contoh,
dan sekarang kita bisa menggunakan variabel global:
Modifikasi variabel global dari dalam suatu fungsi
Untuk mengarahkan variabel global ke objek yang berbeda, Anda harus menggunakan kata kunci global lagi:
Perhatikan bahwa setelah menulis fungsi ini, kode sebenarnya mengubahnya masih belum berjalan:
Jadi setelah memanggil fungsi:
kita dapat melihat bahwa variabel global telah diubah. The
global_variable
nama sekarang menunjuk ke'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:
Tetapi menggunakan variabel lokal yang salah nama itu tidak mengubah variabel global:
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:
Di sini saya menunjukkan kita mendapatkan perilaku yang sama dalam metode seperti yang kita lakukan dalam fungsi reguler:
Dan sekarang:
Tapi saya sarankan daripada menggunakan variabel global Anda menggunakan atribut kelas, untuk menghindari kekacauan namespace modul. Perhatikan juga, kami tidak menggunakan
self
argumen di sini - ini bisa berupa metode kelas (berguna jika mengubah atribut kelas daricls
argumen biasa ) atau metode statis (tidakself
ataucls
).sumber
Selain jawaban yang sudah ada dan untuk membuatnya lebih membingungkan:
Sumber: Apa aturan untuk variabel lokal dan global dalam Python? .
sumber
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:
Keluaran:
sumber
Apa yang Anda katakan adalah menggunakan metode seperti ini:
Tetapi cara yang lebih baik adalah dengan menggunakan variabel global seperti ini:
Keduanya memberikan output yang sama.
sumber
Ternyata jawabannya selalu sederhana.
Berikut ini adalah contoh modul kecil dengan cara sederhana untuk menunjukkannya dalam
main
definisi:Berikut ini cara menunjukkannya dalam
main
definisi:Kode sederhana ini berfungsi begitu saja, dan itu akan dijalankan. Saya harap ini membantu.
sumber
global_vars
, dan menginisialisasi datainit_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!Anda perlu referensi variabel global di setiap fungsi yang ingin Anda gunakan.
Sebagai berikut:
sumber
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.
sumber
Coba ini:
sumber
Jika Anda memiliki variabel lokal dengan nama yang sama, Anda mungkin ingin menggunakan
globals()
fungsinya .sumber
Setelah dan sebagai tambahan, gunakan file untuk memuat semua variabel global yang semuanya dideklarasikan secara lokal lalu
import as
:File initval.py :
File getstocks.py :
sumber
import ... as ...
? Kenapa tidak adilimport ...
?global
:-) => +1 :-) Harap edit jawaban Anda untuk menjelaskan interogasi yang mungkin dimiliki orang lain. CheersMenulis ke elemen eksplisit dari array global tampaknya tidak memerlukan deklarasi global, meskipun menulis kepadanya "grosir" memang memiliki persyaratan:
sumber
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:dan
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.
sumber
globals()
selalu mengembalikan global yang tersedia dalam konteks lokal, jadi mutasi di sini mungkin tidak tercermin dalam modul lain.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
main / runner.py
tes / runner_test.py
sumber
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 ...
Mereka berbeda dalam alokasi memori inisialisasi ... (tapi saya tidak membahas ini di sini).
Mari kita lihat masalah / contohnya ...
Windows
Jika Anda menjalankan ini pada Windows (Dan saya kira pada MacOS juga), Anda mendapatkan output berikut ...
Linux
Jika Anda menjalankan ini di Linux, Anda mendapatkan yang berikut ini.
sumber