Bir fonksiyonda global değişkenleri kullanma


3114

Bir işlevde nasıl global değişken oluşturabilirim veya kullanabilirim?

Bir işlevde genel değişken oluşturursam, bu genel değişkeni başka bir işlevde nasıl kullanabilirim? Genel değişkeni, erişimini gerektiren işlevin yerel bir değişkeninde depolamam gerekir mi?

Yanıtlar:


4245

Genel bir değişkeni, globalkendisine atanan her işlevde olduğu gibi bildirerek diğer işlevlerde kullanabilirsiniz :

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

Bunun nedeni, küresel değişkenler çok tehlikeli olduğu için, Python'un globalanahtar kelimeyi açıkça isteyerek gerçekten bununla oynadığınızı bildiğinizden emin olmak istediğini hayal ediyorum .

Genel bir değişkeni modüller arasında paylaşmak istiyorsanız diğer yanıtlara bakın.


838
Globallere "çok tehlikeli" demek aşırı abartıdır. Globaller, var olan ve var olacak olan her dilde mükemmel derecede iyidir. Onların yeri var. Söylemeniz gerekenler, nasıl programlanacağına dair hiçbir fikriniz yoksa sorunlara neden olabilirler.
Anthony

207
Bence oldukça tehlikeliler. Ancak python "global" değişkenleri aslında modül düzeyindedir, bu da birçok sorunu çözer.
Fábio Santos

246
Python'un globalanahtar kelimeyi gerektirmesinin sebebi , küresellerin tehlikeli olmasından kaynaklanmıyor. Aksine, dilin açıkça değişkenleri bildirmenizi gerektirmemesi ve aksi belirtilmedikçe, atadığınız bir değişkenin işlev kapsamına sahip olduğunu otomatik olarak varsaymasıdır. globalAnahtar kelime başka bir şey isteyene verilir araçtır.
Nate CK

7
@avgvstvs: Aynı programı globaller olmadan uyguluyorsanız, yine de aynı sayıda kod yoluna sahipsiniz. Yaptığınız argüman küresellere karşı değil.
Yörüngedeki Hafiflik Yarışları

13
@LightnessRacesinOrbit Ne demek istediğimi anlayamıyorum. Genel bir değişkeni kaldırırsanız, karmaşık faktörü şimdi kaldırırsınız, çünkü rasgele işlevler artık yürütmenin çeşitli noktalarında program durumunu değiştiremez - böylece yürütmeyi, bu değişkene dayanan diğer işlevlerle algılanamayacak şekilde değiştirir. Artık, "Did izlemek zorunda f2()durum değiştirmek yani şimdi f3()? Beklenmeyen bir şey yapabilir fonksiyonları artık dış program durumuna agnostik çalışabilir.
avgvstvs

775

Durumunuzu doğru bir şekilde anlıyorsam, gördüğünüz şey Python'un yerel (işlev) ve genel (modül) ad alanlarını nasıl işlediğinin sonucudur.

Diyelim ki böyle bir modülünüz var:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

Bu 42 yazdırmaya bekliyor olabilir, ancak bir 'eklerseniz bunun yerine, 5. Daha önce bahsedildiği yazdırır globaliçin' beyanı func1()sonra, func2()42 yazdırılır.

def func1():
    global myGlobal
    myGlobal = 42

Burada olup bitenler, Python'un , bir işlev içinde herhangi bir yere atanan herhangi bir adın, aksi açıkça belirtilmediği sürece bu işlev için yerel olduğunu varsayar . Yalnızca bir addan okuyorsa ve ad yerel olarak mevcut değilse, adı içeren kapsamlarda (örneğin, modülün global kapsamı) aramaya çalışır.

Bu myGlobalnedenle ada 42 atadığınızda , Python aynı adın genel değişkenini gölgeleyen yerel bir değişken oluşturur. Yerel kapsam dışına gider ve olduğu çöp toplama zaman func1()döner; bu arada, func2()(değiştirilmemiş) global ad dışında hiçbir şey göremezsiniz. Bu ad alanı kararının derleme zamanında değil, çalışma zamanında gerçekleştiğine dikkat edin - atamadan önce myGlobaliçerideki değeri okuyacak func1()olsaydınız, alırsınız UnboundLocalError, çünkü Python zaten yerel bir değişken olmasına karar verdi, ancak henüz onunla ilişkili bir değere sahip değil. Ancak ' global' ifadesini kullanarak, Python'a yerel olarak atamak yerine ad için başka bir yere bakması gerektiğini söylersiniz.

(Bu davranışın büyük ölçüde yerel ad alanlarının optimizasyonundan kaynaklandığına inanıyorum - bu davranış olmadan, Python VM'sinin bir işlev içinde her yeni bir ad atandığında en az üç ad araması yapması gerekir (adın t zaten modül / yerleşik düzeyde mevcut), bu çok yaygın bir işlemi önemli ölçüde yavaşlatır.)


Ad alanı kararının derleme zamanında gerçekleştiğinden bahsettiniz, bunun doğru olduğunu düşünmüyorum. öğrendiğim kadarıyla python'un derlemesi sadece sözdizimi hatasını kontrol eder, ad hatası değil bu örneği deneyin def A (): x + = 1 , eğer çalıştırmazsanız, UnboundLocalError vermez , lütfen teşekkür ederim doğrulayın
watashiSHUN

1
Küresel değişkenler için büyük harf kullanmak yaygındırMyGlobal = 5
Vassilis

3
@watashiSHUN: namespace karar vermez derleme sırasında olur. xYerel olduğuna karar vermek , yerel adın ilk kez kullanılmadan önce bir değere bağlı olup olmadığını çalışma zamanında denetlemekten farklıdır.
BlackJack

9
@Vassilis: Bu harf için ortak tüm harfler: MY_GLOBAL = 5. Python Kodu için Stil Kılavuzuna bakın .
BlackJack

223

Ad alanları kavramını keşfetmek isteyebilirsiniz . Python'da, modül küresel veriler için doğal bir yerdir :

Her modülün, modülde tanımlanan tüm işlevler tarafından genel sembol tablosu olarak kullanılan kendi özel sembol tablosu vardır. Böylece, bir modülün yazarı, bir kullanıcının global değişkenleriyle yanlışlıkla çarpışmadan endişe etmeden modüldeki global değişkenleri kullanabilir. Öte yandan, ne yaptığınızı biliyorsanız, bir modülün işlevlerine atıfta bulunmak için kullanılan aynı gösterime sahip global değişkenlere dokunabilirsiniz modname.itemname.

Genel modül içinde özel kullanımı burada açıklanmıştır - Genel değişkenleri modüller arasında nasıl paylaşabilirim? ve eksiksiz olması için içerik burada paylaşılır:

Tek bir programda modüller arasında bilgi paylaşmanın standart yolu, özel bir yapılandırma modülü (genellikle config veya cfg olarak adlandırılır) oluşturmaktır ) oluşturmaktır. Yapılandırma modülünü uygulamanızın tüm modüllerine aktarmanız yeterlidir; modül global bir ad olarak kullanılabilir hale gelir. Her modülün yalnızca bir örneği olduğundan, modül nesnesinde yapılan değişiklikler her yere yansıtılır. Örneğin:

Dosya: config.py

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

Dosya: mod.py

import config
config.x = 1

Dosya: main.py

import config
import mod
print config.x

1
bir nedenle config.x ondan kurtulabilir miyim? Geldim x = lambda: config.xve sonra yeni bir değere sahibim x(). bir nedenden dolayı, sahip olmak a = config.xbenim için hile yapmaz.
vladosaurus

3
@vladosaurus bunu from config import xçözüyor mu?
jhylands

93

Python, hangi kapsamdan yerel ve küresel arasında bir değişken yüklemesi gerektiğine karar vermek için basit bir buluşsal yöntem kullanır. Bir ödevin sol tarafında bir değişken adı görünüyor ancak global olarak bildirilmiyorsa, yerel olduğu varsayılır. Bir ödevin sol tarafında görünmezse, küresel olduğu varsayılır.

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

Bir ödevin sol tarafında görünen baz'ın foo()tek LOAD_FASTdeğişken olduğunu görün.


12
Buluşsal yöntem, bağlayıcı işlemleri arar . Atama böyle bir işlem, diğerini içe aktarır. Ama bir hedef fordöngü ve sonra adı asiçinde withve exceptifadeleri de bağlanmıştır.
Martijn Pieters

@MartijnPieters asBir exceptmaddeden sonraki isim için bu benim için açık değildi. Ancak hafızadan tasarruf etmek için otomatik olarak silinir.
Robert

1
@Robert: bellekten tasarruf etmek için değil, bellek sızıntılarına neden olabilecek dairesel bir referans oluşturmaktan kaçının. Bunun nedeni, bir istisnanın bir geri izlemeye başvurması ve geri izlemenin as ..., istisna işleyicisindeki hedef de dahil olmak üzere tüm çağrı yığını boyunca her yerel ve global ad alanına başvurmasıdır .
Martijn Pieters

62

Bir işlevdeki bir genel değişkene başvurmak istiyorsanız, genel hangi değişkenlerin genel olduğunu bildirmek anahtar sözcüğünü . Her durumda kullanmak zorunda değilsiniz (burada birinin yanlış iddia ettiği gibi) - bir ifadede atıfta bulunulan ad yerel kapsamda bulunamazsa veya bu işlevin tanımlandığı işlevlerin kapsamlarında bulunamazsa, genel değişkenler.

Ancak, işlevde global olarak bildirilmeyen yeni bir değişkene atarsanız, dolaylı olarak yerel olarak bildirilir ve aynı ada sahip varolan herhangi bir genel değişkeni gölgede bırakabilir.

Ayrıca, küresel değişkenler, aksi halde iddia eden bazı OOP zekâllerinin aksine, özellikle OOP'un aşırı dolu olduğu daha küçük komut dosyaları için kullanışlıdır.


Kesinlikle yeniden. fanatikler. Çoğu Python kullanıcısı komut dosyası oluşturmak için kullanır ve küçük kod parçalarını ayırmak için küçük işlevler oluşturur.
Paul Uszak

51

Bir işlevde genel değişken oluşturursam, bu değişkeni başka bir işlevde nasıl kullanabilirim?

Aşağıdaki işlevle bir global oluşturabiliriz:

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' 

Bir işlev yazmak aslında kodunu çalıştırmaz. Bu yüzden create_global_variableişlevi çağırırız :

>>> create_global_variable()

Globalleri değişiklik yapmadan kullanma

Hangi nesneyi işaret ettiğini değiştirmeyi beklemediğiniz sürece kullanabilirsiniz.

Örneğin,

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

ve şimdi global değişkeni kullanabiliriz:

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

Bir fonksiyonun içinden global değişkenin değiştirilmesi

Genel değişkeni farklı bir nesneye yönlendirmek için genel anahtar kelimeyi tekrar kullanmanız gerekir:

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

Bu işlevi yazdıktan sonra, aslında değiştiren kodun hala çalışmadığını unutmayın:

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

Yani işlevi çağırdıktan sonra:

>>> change_global_variable()

küresel değişkenin değiştiğini görebiliriz. global_variableAdı artık işaret 'Bar':

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

Python'daki "global" değerin gerçekten global olmadığını unutmayın - sadece modül düzeyinde globaldir. Bu yüzden sadece küresel olduğu modüllerde yazılan fonksiyonlar için kullanılabilir. İşlevler, yazıldıkları modülü hatırlar, bu nedenle diğer modüllere dışa aktarıldıklarında, küresel değişkenleri bulmak için oluşturuldukları modüle bakarlar.

Aynı ada sahip yerel değişkenler

Aynı ada sahip bir yerel değişken oluşturursanız, global bir değişkeni gölgede bırakır:

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

Ancak bu yanlış adlandırılmış yerel değişkeni kullanmak genel değişkeni değiştirmez:

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

Ne yaptığınızı tam olarak bilmiyorsanız ve bunu yapmak için çok iyi bir nedeniniz yoksa, global değişkenlerle aynı adlara sahip yerel değişkenleri kullanmaktan kaçınmanız gerektiğini unutmayın. Henüz böyle bir sebeple karşılaşmadım.

Sınıflarda aynı davranışı elde ederiz

Yorum takip edildiğinde:

bir sınıf içindeki bir işlevin içinde global bir değişken oluşturmak ve başka bir sınıf içindeki başka bir işlevin içindeki bu değişkeni kullanmak istersem ne yapmalıyım?

Burada, düzenli işlevlerde yaptığımız yöntemlerle aynı davranışı elde ettiğimizi göstereceğim:

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

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

Foo().foo()

Ve şimdi:

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

Ancak modül ad alanını karmaşıklaştırmaktan kaçınmak için global değişkenleri kullanmak yerine sınıf özniteliklerini kullanırsınız. Ayrıca selfburada argümanlar kullanmadığımızı unutmayın - bunlar sınıf yöntemleri (sınıf niteliğini normal clsargümandan mutasyona uğrarsa kullanışlıdır ) veya statik yöntemler (hayır selfveya cls) olabilir.


Harika, ama bir sınıf içindeki bir fonksiyonun içinde global bir değişken oluşturmak ve bu değişkeni başka bir sınıfın içindeki başka bir fonksiyonun içinde kullanmak istersem ne yapmalıyım?
Tür

2
@anonmanx Neden takıldığınızı bilmiyorum, bu normal bir fonksiyondaki yöntemle aynı davranış. Ama cevabımı sözlerinle ve bazı demo koduyla güncelleyeceğim, tamam mı?
Aaron Hall

1
@anonmanx bu nasıl?
Aaron Hall

tamam anladım. Bu yüzden açıkça bu değişkeni kullanmak için bu işlevi çağırmak zorunda kalacak.
anonmanx

47

Mevcut cevaplara ek olarak ve bunu daha karmaşık hale getirmek için:

Python'da, yalnızca bir işlev içinde başvurulan değişkenler dolaylı olarak geneldir . Bir değişkene fonksiyonun gövdesinde herhangi bir yerde yeni bir değer atanırsa, yerel olarak kabul edilir . Bir değişkene işlev içinde yeni bir değer atanırsa, değişken dolaylı olarak yereldir ve bunu açıkça 'global' olarak bildirmeniz gerekir.

İlk başta biraz şaşırtıcı olsa da, bir anın düşüncesi bunu açıklıyor. Bir yandan, atanan değişkenler için global gereksinimi, istenmeyen yan etkilere karşı bir çubuk sağlar. Öte yandan, tüm global referanslar için global gerekiyorsa, her zaman global kullanırsınız. Yerleşik bir işleve veya içe aktarılan bir modülün her bileşenine yapılan her başvuruyu genel olarak bildirmeniz gerekir. Bu karmaşa, yan etkilerin tanımlanması için küresel bildirgenin yararlılığını bozacaktır.

Kaynak: Python'daki yerel ve global değişkenler için kurallar nelerdir? .


34

Paralel yürütme ile, ne olduğunu anlamıyorsanız genel değişkenler beklenmedik sonuçlara neden olabilir. Aşağıda, çoklu işlemede genel bir değişken kullanımına bir örnek verilmiştir. Her sürecin, değişkenin kendi kopyasıyla çalıştığını açıkça görebiliriz:

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

Çıktı:

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]

25

Söylediğiniz yöntem bu şekilde kullanmaktır:

globvar = 5

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

f()  # Prints 5

Ancak daha iyi bir yol, küresel değişkeni şu şekilde kullanmaktır:

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

Her ikisi de aynı çıktıyı verir.


25

Anlaşıldığı gibi, cevap her zaman basittir.

İşte bir maintanımda göstermenin basit bir yoluna sahip küçük bir örnek modül :

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

def isTheNumber():
    return helper

Bir maintanımda nasıl gösterileceği aşağıda açıklanmıştır :

import TestPy

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

if __name__ == '__main__':
    main()

Bu basit kod aynı şekilde çalışır ve yürütülür. Umut ediyorum bu yardım eder.


1
teşekkürler, python için yeniyim, ama biraz java biliyorum. söylediğin benim için çalıştı. ve global sınıfta bir <ENTER> yazmak .. bana 'global a' yazma fonksiyonundan daha mantıklı geliyor.
Ekim'de

2
Bu muhtemelen benim için en basit ama çok kullanışlı python hilesi. Bu modülü adlandırıyorum ve başlangıç ​​komut dosyasında çağrılan global_varsverileri init_global_varsbaşlatıyorum. Sonra, sadece tanımlanmış her global var. Umarım bunu birden fazla kez değerlendirebilirim! Teşekkürler Peter!
swdev

1
Çok sayıda global değişken varsa ve bunları global bir ifadeden sonra tek tek listelemek istemiyorsam ne olur?
jtlz2

23

Kullanmak istediğiniz her işlevde global değişkene başvurmanız gerekir.

Aşağıdaki gibi:

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

3
'
Kullanmak

21

Global olanı yerel bir değişkende saklamıyorsunuz, sadece orijinal global referansınızın başvurduğu nesneye yerel bir referans oluşturuyorsunuz. Python'daki hemen hemen her şeyin bir nesneye atıfta bulunan bir isim olduğunu ve normal işlemde hiçbir şeyin kopyalanmadığını unutmayın.

Bir tanımlayıcının önceden tanımlanmış bir global değere ne zaman başvuracağını açıkça belirtmeniz gerekmediyse, muhtemelen tanımlayıcının ne zaman yeni bir yerel değişken olduğunu açıkça belirtmeniz gerekir (örneğin, 'var' komutu gibi bir şeyle) JavaScript'te görüldü). Ciddi ve önemsiz olmayan sistemlerde yerel değişkenler küresel değişkenlerden daha yaygın olduğundan, Python'un sistemi çoğu durumda daha mantıklıdır.

Sen olabilir o var ya o olmasaydı yerel bir değişken oluşturmak eğer küresel bir değişkeni kullanarak, tahmin girişiminde bulunan dili var. Ancak, bu hataya çok açıktır. Örneğin, başka bir modülün içe aktarılması yanlışlıkla programınızın davranışını değiştirerek bu ada göre global bir değişken oluşturabilir.


17

Bunu dene:

def x1():
    global x
    x = 6

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

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


14

Eklentiyi izleyip eklerken, yerel olarak bildirilen tüm genel değişkenleri içerecek bir dosya kullanın ve ardından import as :

Dosya initval.py :

Stocksin = 300
Prices = []

Dosya getstocks.py :

import initval as iv

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


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

1
Global değişkenleri başka bir dosyaya taşımanın avantajı nedir? Sadece küresel değişkenleri küçük bir dosyada gruplamak mı? Ve neden bu ifadeyi kullanıyorsunuz import ... as ...? Neden sadece import ...?
olibre

1
Ah ... Sonunda avantajı anladım: global:-) => +1 :-) anahtar kelimesini kullanmaya gerek yok. Lütfen diğer kişilerin de sahip olabileceği bu sorgulamaları netleştirmek için cevabınızı düzenleyin. Şerefe
olibre

13

Genel dizinin açık öğelerine yazmak, genel olarak bildirime ihtiyaç duymaz, ancak buna "toptan satış" yazmak için şu gereksinime sahiptir:

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

7

Bunu diğer cevapların hiçbirinde görmediğim için ekliyorum ve benzer bir şeyle mücadele eden biri için yararlı olabilir. globals()İşlevi, bir değişken küresel bir simge sözlüğü döner nerede kodunun geri kalanı için kullanılabilir yapabilirsiniz "sihirli" marka verileri. Örneğin:

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

ve

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

Değişkenleri genel ad alanının dışına ve dışına dökmenize izin verir. Süper uygun, muss yok, karışıklık yok. Sadece Python 3 olduğundan eminim.


3
globals()her zaman yerel bağlamda kullanılabilir globalleri döndürür, bu nedenle buradaki bir mutasyon başka bir modüle yansıtmayabilir.
Kiran Jonnalagadda

6

Değişikliğin görünmesini istediğiniz sınıf ad alanına başvurun.

Bu örnekte runner, config dosyasından max kullanıyor . Testimin runner kullanırken max değerini değiştirmesini istiyorum .

Ana / config.py

max = 15000

Ana / runner.py

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

Testler / 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()

1

Globaller gayet iyi - Çoklu İşlem Hariç

Bir tarafta Windows / Mac OS ve diğer tarafta Linux gibi farklı platformlarda / ortamlarda çoklu işlemle bağlantılı küreseller zahmetlidir.

Bunu size, bir süre önce karşılaştığım bir sorunu gösteren basit bir örnekle göstereceğim.

Windows / MacOs ve Linux'ta neden farklı olduğunu anlamak istiyorsanız, bilmeniz gereken yeni bir işlem başlatmak için varsayılan mekanizma ...

  • Windows / MacO'lar 'doğuyor'
  • Linux 'çatal'

Bellek tahsisi başlatma işleminde farklıdırlar ... (ama buraya girmiyorum).

Soruna bir göz atalım / örnek ...

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)

pencereler

Bunu Windows'ta çalıştırırsanız (Ve sanırım MacOS'ta da), aşağıdaki çıktıyı alırsınız ...

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

Linux

Bunu Linux'ta çalıştırırsanız, bunun yerine aşağıdakileri elde edersiniz.

task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.