किसी फ़ंक्शन में वैश्विक चर का उपयोग करना


3112

मैं किसी फ़ंक्शन में वैश्विक चर कैसे बना या उपयोग कर सकता हूं?

यदि मैं एक फ़ंक्शन में एक वैश्विक चर बनाता हूं, तो मैं दूसरे फ़ंक्शन में उस वैश्विक चर का उपयोग कैसे कर सकता हूं? क्या मुझे फ़ंक्शन के स्थानीय चर में वैश्विक चर को संग्रहीत करने की आवश्यकता है जो इसकी पहुंच की आवश्यकता है?

जवाबों:


4243

आप इसे कार्य करने वाले globalप्रत्येक फ़ंक्शन में घोषित करके अन्य कार्यों में एक वैश्विक चर का उपयोग कर सकते हैं :

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

मैं इसका कारण कल्पना करता हूं कि चूंकि वैश्विक चर इतने खतरनाक हैं, पाइथन यह सुनिश्चित करना चाहता है कि आप वास्तव में जानते हैं कि आप globalकीवर्ड की आवश्यकता के साथ स्पष्ट रूप से खेल रहे हैं ।

अन्य उत्तर देखें यदि आप मॉड्यूल में एक वैश्विक चर साझा करना चाहते हैं।


838
ग्लोबल्स को "इतने खतरनाक" के रूप में संदर्भित करना अतिशयोक्ति है। ग्लोबल्स हर भाषा में पूरी तरह से ठीक हैं जो कभी भी अस्तित्व में हैं और कभी भी मौजूद होंगी। उनका स्थान है। आपको जो कहना चाहिए था, वह यह है कि वे मुद्दे पैदा कर सकते हैं यदि आपके पास कोई सुराग नहीं है कि कैसे प्रोग्राम किया जाए।
एंथनी

207
मुझे लगता है कि वे काफी खतरनाक हैं। हालांकि अजगर "वैश्विक" चर वास्तव में मॉड्यूल-स्तर हैं, जो बहुत सारे मुद्दों को हल करता है।
फैबियो सांतोस

246
मैं इस बात से असहमत हूं कि पायथन को globalकीवर्ड की आवश्यकता है क्योंकि ग्लोबल्स खतरनाक हैं। इसके बजाय, यह इसलिए है क्योंकि भाषा को आपको स्पष्ट रूप से चर घोषित करने की आवश्यकता नहीं होती है और स्वचालित रूप से मान लिया जाता है कि आपके द्वारा असाइन किया गया चर में फ़ंक्शन गुंजाइश है जब तक कि आप इसे अन्यथा नहीं बताते। globalकीवर्ड का मतलब है कि यह अन्यथा बताने के लिए प्रदान की जाती है।
नैट सीके

7
@avgvstvs: और यदि आप ग्लोबल्स के बिना एक ही कार्यक्रम लागू कर रहे हैं, तो आपके पास अभी भी समान कोड पथ हैं। आपने जो तर्क दिया है वह ग्लोबल्स के खिलाफ नहीं है।
को ऑर्बिट

13
@LightnessRacesinOrbit मुझे आपकी बात रास नहीं आ रही है। यदि आप एक वैश्विक चर निकालते हैं, तो आप उस जटिल जटिलता को दूर कर देते हैं, जो मनमाने कार्य अब प्रोग्राम स्टेट को बदल नहीं सकते हैं, निष्पादन में विभिन्न बिंदुओं पर - इस प्रकार निष्पादन को एक तरह से बदल सकते हैं, अन्यथा उस चर पर निर्भर अन्य कार्यों के लिए अपरिहार्य है। अब आपको नज़र रखने की ज़रूरत नहीं है, "क्या f2()राज्य बदल गया है इसलिए अब f3()कुछ अप्रत्याशित हो सकता है? कार्य अब बाहरी कार्यक्रम राज्य के लिए अज्ञेय को संचालित कर सकते हैं।
avgvstvs

775

यदि मैं आपकी स्थिति को सही ढंग से समझ रहा हूं, तो आप जो देख रहे हैं, वह परिणाम है कि पायथन स्थानीय (फ़ंक्शन) और वैश्विक (मॉड्यूल) नामस्थानों को कैसे संभालता है।

कहें कि आपको इस तरह एक मॉड्यूल मिला है:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

आप इसे 42 को प्रिंट करने की उम्मीद कर सकते हैं, लेकिन इसके बजाय यह 5. प्रिंट करता है। जैसा कि पहले ही उल्लेख किया गया है, यदि आप ' global' घोषणा को जोड़ते हैं func1(), तो func2()42 को प्रिंट करेगा।

def func1():
    global myGlobal
    myGlobal = 42

यहाँ क्या हो रहा है कि पायथन मानता है कि किसी भी नाम को , जो एक फ़ंक्शन के लिए , कहीं भी सौंपा गया है , उस फ़ंक्शन के लिए स्थानीय है जब तक कि स्पष्ट रूप से अन्यथा नहीं बताया जाता है। यदि यह केवल एक नाम से पढ़ रहा है, और यह नाम स्थानीय रूप से मौजूद नहीं है, तो यह किसी भी स्कोप में नाम देखने की कोशिश करेगा (जैसे मॉड्यूल का वैश्विक दायरा)।

जब आप नाम को 42 असाइन करते हैं myGlobal, इसलिए, पायथन एक स्थानीय चर बनाता है जो उसी नाम के वैश्विक चर को छाया देता है। वह स्थानीय दायरे से बाहर हो जाता है और वापस लौटने पर कचरा एकत्र किया जाता func1()है; इस बीच, func2()वैश्विक नाम (अनमॉडिफाइड) के अलावा कुछ भी नहीं देख सकते हैं। ध्यान दें कि यह नाम स्थान निर्णय संकलित समय पर होता है, रनटाइम पर नहीं - यदि आप इसे असाइन करने से पहले myGlobalअंदर का मूल्य पढ़ना func1()चाहते हैं, तो आपको एक मिलेगा UnboundLocalError, क्योंकि पायथन ने पहले ही तय कर लिया है कि यह एक स्थानीय चर होना चाहिए लेकिन यह अभी तक इसके साथ कोई मूल्य नहीं जुड़ा है। लेकिन ' global' कथन का उपयोग करके , आप पायथन को बताते हैं कि इसे स्थानीय रूप से निर्दिष्ट करने के बजाय नाम के लिए कहीं और देखना चाहिए।

(मेरा मानना ​​है कि यह व्यवहार काफी हद तक स्थानीय नामस्थानों के अनुकूलन के माध्यम से उत्पन्न हुआ है - इस व्यवहार के बिना, पायथन के वीएम को एक समारोह के अंदर (यह सुनिश्चित करने के लिए कि नया नाम सौंपा गया है) को हर बार एक नया नाम सौंपा जाना चाहिए। टी पहले से ही मॉड्यूल / बिलिन स्तर पर मौजूद है), जो बहुत सामान्य ऑपरेशन को धीमा कर देगा।)


आपने उल्लेख किया है कि नाम स्थान का निर्णय संकलन समय पर होता है , मुझे नहीं लगता कि यह सच है। जो मैं अजगर के संकलन को केवल सिंटैक्स त्रुटि के लिए जांचता हूं, से सीखता हूं , नाम त्रुटि नहीं, इस उदाहरण को ए (डी): x + = 1 के उदाहरण के रूप में देखें , यदि आप इसे नहीं चलाते हैं, तो यह अनबाउंडलोक्यूर्रर नहीं देगा , कृपया धन्यवाद सत्यापित करें
वशिताअन

1
वैश्विक चरों के लिए बड़े अक्षर का उपयोग करना आम हैMyGlobal = 5
वासिलिस

3
@watashiSHUN: नाम स्थान निर्णय करता संकलन समय पर होता है। यह तय करना कि xस्थानीय नाम रनटाइम पर जाँच करने से अलग है यदि पहली बार उपयोग किए जाने से पहले स्थानीय नाम एक मूल्य के लिए बाध्य था।
ब्लैकजैक

9
@ वासिलिस: ऊपरी अक्षरों के सभी मामलों में यह आम है MY_GLOBAL = 5:। पायथन कोड के लिए स्टाइल गाइड देखें ।
ब्लैकजैक

223

आप नामस्थानों की धारणा का पता लगाना चाह सकते हैं । पायथन में, मॉड्यूल वैश्विक डेटा के लिए प्राकृतिक स्थान है :

प्रत्येक मॉड्यूल की अपनी निजी प्रतीक तालिका होती है, जिसका उपयोग मॉड्यूल में परिभाषित सभी कार्यों द्वारा वैश्विक प्रतीक तालिका के रूप में किया जाता है। इस प्रकार, एक मॉड्यूल का लेखक उपयोगकर्ता के वैश्विक चर के साथ आकस्मिक संघर्ष के बारे में चिंता किए बिना मॉड्यूल में वैश्विक चर का उपयोग कर सकता है। दूसरी ओर, यदि आप जानते हैं, क्या आप आप एक ही अपने कार्यों के लिए किया जाता अंकन के साथ एक मॉड्यूल के वैश्विक चर छू सकता है कर रहे हैं modname.itemname

ग्लोबल-इन-ए-मॉड्यूल का एक विशिष्ट उपयोग यहां वर्णित है - मैं मॉड्यूल भर में वैश्विक चर कैसे साझा करूं? , और पूर्णता के लिए सामग्री यहाँ साझा की जाती है:

एकल कार्यक्रम के भीतर मॉड्यूल को जानकारी साझा करने का विहित तरीका एक विशेष कॉन्फ़िगरेशन मॉड्यूल (जिसे अक्सर कॉन्फ़िगरेशन या सीएफजी कहा जाता है ) बनाना है। बस अपने एप्लिकेशन के सभी मॉड्यूल में कॉन्फ़िगरेशन मॉड्यूल आयात करें; मॉड्यूल तब वैश्विक नाम के रूप में उपलब्ध हो जाता है। क्योंकि प्रत्येक मॉड्यूल का केवल एक उदाहरण है, मॉड्यूल ऑब्जेक्ट में किए गए कोई भी परिवर्तन हर जगह परिलक्षित होते हैं। उदाहरण के लिए:

फ़ाइल: config.py

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

फ़ाइल: mod.py

import config
config.x = 1

फ़ाइल: मेनहोम

import config
import mod
print config.x

1
एक कारण के लिए मुझे पसंद नहीं है क्या config.x मैं इससे छुटकारा पा सकता हूं? मैं साथ आया x = lambda: config.xऔर फिर मेरे पास नया मूल्य है x()। किसी कारण से, a = config.xमेरे लिए चाल नहीं चल रहा है।
vladosaurus

3
@vladosaurus इसका from config import xसमाधान करता है?
झाइंड्स

93

पाइथन यह तय करने के लिए एक साधारण हेयुरिस्टिक का उपयोग करता है कि उसे स्थानीय और वैश्विक के बीच किस चर को लोड करना चाहिए। यदि एक असाइनमेंट के बाईं ओर एक चर नाम दिखाई देता है, लेकिन वैश्विक घोषित नहीं किया जाता है, तो इसे स्थानीय माना जाता है। यदि यह एक असाइनमेंट के बाईं ओर दिखाई नहीं देता है, तो इसे वैश्विक माना जाता है।

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

देखें कि कैसे बाज़, जो एक असाइनमेंट के बाईं ओर दिखाई देता foo()है, एकमात्र LOAD_FASTचर है।


12
बाध्यकारी संचालन के लिए अनुमानी दिखता है । असाइनमेंट एक ऐसा ऑपरेशन है, जो दूसरा आयात करता है। लेकिन एक का लक्ष्य forपाश और बाद नाम asमें withऔर exceptबयान भी करने के लिए बाध्य कर रहे हैं।
मार्टिन पीटर्स

@MartijnPieters asएक exceptक्लॉज में नाम के बाद यह मेरे लिए स्पष्ट नहीं था। लेकिन यह मेमोरी को बचाने के लिए ऑटो-डिलीट हो जाता है।
राबर्ट

1
@ रॉबर्ट: स्मृति को बचाने के लिए नहीं, बल्कि एक परिपत्र संदर्भ बनाने से बचने के लिए, जिससे मेमोरी लीक हो सकती है। ऐसा इसलिए है क्योंकि एक अपवाद एक ट्रेसबैक का संदर्भ देता है, और ट्रेसबैक प्रत्येक स्थानीय और वैश्विक नाम स्थान को संपूर्ण कॉल स्टैक के साथ संदर्भित करता है, जिसमें as ...अपवाद हैंडलर में लक्ष्य भी शामिल है ।
मार्टिन पीटर्स

62

यदि आप किसी फ़ंक्शन में वैश्विक चर को संदर्भित करना चाहते हैं, तो आप वैश्विक का उपयोग कर सकते हैं कीवर्ड का घोषित करने के लिए कौन से चर वैश्विक हैं। आपको इसे सभी मामलों में उपयोग नहीं करना है (जैसा कि यहां कोई गलत दावा करता है) - यदि अभिव्यक्ति में संदर्भित नाम स्थानीय कार्यक्षेत्रों में या उन कार्यों में स्कोप नहीं मिल सकता है जिसमें यह कार्य परिभाषित है, तो इसे वैश्विक स्तर पर देखा जाता है। चर।

हालाँकि, यदि आप किसी नए चर को फ़ंक्शन में वैश्विक घोषित नहीं करते हैं, तो इसे स्थानीय रूप से घोषित किया जाता है, और यह किसी भी मौजूदा वैश्विक चर को उसी नाम से देख सकता है।

इसके अलावा, वैश्विक चर उपयोगी हैं, कुछ ओओपी ज़ीलोट्स के विपरीत, जो अन्यथा दावा करते हैं - विशेष रूप से छोटी लिपियों के लिए, जहां ओओपी ओवरकिल है।


बिल्कुल फिर से। उग्रपंथियों। अधिकांश पायथन उपयोगकर्ता इसे स्क्रिप्टिंग के लिए उपयोग करते हैं और कोड के छोटे बिट्स को अलग करने के लिए बहुत कम फ़ंक्शन बनाते हैं।
पॉल उस्ज़ाक

51

यदि मैं एक फ़ंक्शन में एक वैश्विक चर बनाता हूं, तो मैं दूसरे चर में उस चर का उपयोग कैसे कर सकता हूं?

हम निम्नलिखित फ़ंक्शन के साथ एक वैश्विक बना सकते हैं:

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' 

एक फ़ंक्शन लिखना वास्तव में अपना कोड नहीं चलाता है। इसलिए हम create_global_variableफ़ंक्शन को कॉल करते हैं:

>>> create_global_variable()

बिना संशोधन के ग्लोबल्स का उपयोग करना

आप बस इसका उपयोग कर सकते हैं, इसलिए जब तक आप यह बदलने की उम्मीद नहीं करते हैं कि यह किस वस्तु की ओर इशारा करता है:

उदाहरण के लिए,

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

और अब हम वैश्विक चर का उपयोग कर सकते हैं:

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

किसी फ़ंक्शन के अंदर से वैश्विक चर का संशोधन

किसी भिन्न ऑब्जेक्ट पर वैश्विक चर को इंगित करने के लिए, आपको फिर से वैश्विक कीवर्ड का उपयोग करना होगा:

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

ध्यान दें कि इस फ़ंक्शन को लिखने के बाद, कोड वास्तव में इसे बदल रहा है अभी भी नहीं चला है:

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

इसलिए फ़ंक्शन को कॉल करने के बाद:

>>> change_global_variable()

हम देख सकते हैं कि वैश्विक चर को बदल दिया गया है। global_variableनाम अब के लिए अंक 'Bar':

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

ध्यान दें कि पायथन में "वैश्विक" वास्तव में वैश्विक नहीं है - यह केवल मॉड्यूल स्तर तक वैश्विक है। इसलिए यह केवल उन मॉड्यूलों में लिखे गए कार्यों के लिए उपलब्ध है जिसमें यह वैश्विक है। फ़ंक्शंस उस मॉड्यूल को याद करते हैं जिसमें वे लिखे गए हैं, इसलिए जब उन्हें अन्य मॉड्यूल में निर्यात किया जाता है, तो वे अभी भी उस मॉड्यूल को देखते हैं जिसमें उन्हें वैश्विक चर खोजने के लिए बनाया गया था।

एक ही नाम के साथ स्थानीय चर

यदि आप एक ही नाम के साथ एक स्थानीय चर बनाते हैं, तो यह एक वैश्विक चर का निरीक्षण करेगा:

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

लेकिन उस गलत स्थानीय चर का उपयोग करने से वैश्विक चर नहीं बदलता है:

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

ध्यान दें कि आपको ग्लोबल्स के समान नामों के साथ स्थानीय चर का उपयोग करने से बचना चाहिए जब तक कि आपको ठीक से पता न हो कि आप क्या कर रहे हैं और ऐसा करने का एक बहुत अच्छा कारण है। मुझे अभी तक ऐसे किसी कारण का सामना नहीं करना पड़ा है।

हमें कक्षाओं में समान व्यवहार मिलता है

टिप्पणी पर एक अनुसरण पूछता है:

अगर मैं एक वर्ग के अंदर एक फ़ंक्शन के अंदर एक वैश्विक चर बनाना चाहता हूं और किसी अन्य वर्ग के अंदर किसी अन्य फ़ंक्शन के अंदर उस चर का उपयोग करना चाहता हूं तो मुझे क्या करना चाहिए?

यहां मैं प्रदर्शित करता हूं कि हमें तरीकों में वैसा ही व्यवहार मिलता है जैसा हम नियमित कार्यों में करते हैं:

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

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

Foo().foo()

और अब:

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

लेकिन मैं मॉड्यूल नाम स्थान को अव्यवस्थित करने से बचने के लिए, आप वैश्विक विशेषताओं का उपयोग करने के बजाय वैश्विक चर का उपयोग करने का सुझाव दूंगा। यह भी ध्यान दें कि हम selfयहाँ तर्कों का उपयोग नहीं करते हैं - ये वर्ग विधियाँ हो सकती हैं (सामान्य clsतर्क से वर्ग गुण को परिवर्तित करना ) या स्थैतिक विधियाँ (नहीं selfया नहीं cls)।


कूल, लेकिन क्या करना है अगर मैं एक वर्ग के अंदर एक फ़ंक्शन के अंदर एक वैश्विक चर बनाना चाहता हूं और किसी अन्य वर्ग के अंदर किसी अन्य फ़ंक्शन के अंदर उस चर का उपयोग करना चाहता हूं?
किन्डा

2
@anonmanx मुझे नहीं पता कि आप क्यों फंस गए हैं, यह एक विधि में एक समान कार्य है जैसा कि एक नियमित कार्य में होता है। लेकिन मैं आपकी टिप्पणी और कुछ डेमो कोड के साथ अपना जवाब अपडेट करूंगा, ठीक है?
हारून हॉल

1
@anonmanx कैसे है?
हारून हॉल

ठीक है समझ आ गया। तो मुझे उस वैश्विक चर का उपयोग करने के लिए स्पष्ट रूप से उस फ़ंक्शन को कॉल करना होगा।
Anonmanx

47

पहले से मौजूद उत्तरों के अलावा और इसे और अधिक भ्रामक बनाने के लिए:

पायथन में, चर जो केवल एक फ़ंक्शन के अंदर संदर्भित होते हैं, वे अंतर्निहित रूप से वैश्विक हैं । यदि किसी चर को फ़ंक्शन के शरीर के भीतर कहीं भी एक नया मान सौंपा गया है, तो इसे स्थानीय माना जाता है । यदि किसी चर को कभी भी फ़ंक्शन के अंदर एक नया मान सौंपा जाता है, तो चर अनुमानित रूप से स्थानीय होता है, और आपको इसे स्पष्ट रूप से 'वैश्विक' घोषित करने की आवश्यकता होती है।

हालांकि पहले तो थोड़ा आश्चर्य हुआ, एक पल का विचार इस बात की व्याख्या करता है। एक तरफ, निर्दिष्ट चर के लिए वैश्विक की आवश्यकता होती है, अनपेक्षित दुष्प्रभावों के खिलाफ एक बार प्रदान करता है। दूसरी ओर, यदि वैश्विक सभी वैश्विक संदर्भों के लिए आवश्यक था, तो आप हर समय वैश्विक उपयोग करेंगे। आपको एक अंतर्निहित फ़ंक्शन या आयातित मॉड्यूल के एक घटक के लिए हर संदर्भ को वैश्विक घोषित करना होगा। यह अव्यवस्था दुष्प्रभावों की पहचान के लिए वैश्विक घोषणा की उपयोगिता को पराजित करेगी।

स्रोत: पायथन में स्थानीय और वैश्विक चर के लिए नियम क्या हैं?


34

समानांतर निष्पादन के साथ, वैश्विक चर अनपेक्षित परिणाम पैदा कर सकते हैं यदि आप समझ नहीं पाते हैं कि क्या हो रहा है। यहां मल्टीप्रोसेसिंग के भीतर एक वैश्विक चर का उपयोग करने का एक उदाहरण है। हम स्पष्ट रूप से देख सकते हैं कि प्रत्येक प्रक्रिया चर की अपनी प्रति के साथ काम करती है:

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

आउटपुट:

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

आप जो कह रहे हैं, वह इस प्रकार है:

globvar = 5

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

f()  # Prints 5

लेकिन बेहतर तरीका यह है कि वैश्विक वैरिएबल का उपयोग इस तरह किया जाए:

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

दोनों एक ही आउटपुट देते हैं।


25

जैसा कि यह पता चला है कि उत्तर हमेशा सरल होता है।

यहाँ एक छोटा सा नमूना मॉड्यूल है जिसे एक mainपरिभाषा में दिखाने का सरल तरीका है :

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

def isTheNumber():
    return helper

इसे mainपरिभाषा में कैसे दिखाया जाए :

import TestPy

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

if __name__ == '__main__':
    main()

यह सरल कोड उसी तरह काम करता है, और यह निष्पादित करेगा। मुझे उम्मीद है यह मदद करेगा।


1
धन्यवाद, मैं अजगर के लिए नया हूँ, लेकिन जावा का एक सा पता है। आपने जो कहा मेरे लिए काम किया। और वैश्विक लेखन
<a>

2
यह शायद मेरे लिए सबसे सरल अभी तक बहुत उपयोगी अजगर चाल है। मैं इस मॉड्यूल का नाम देता हूं global_vars, और डेटा को इनिशियलाइज़ करता हूं , init_global_varsजिसे स्टार्टअप स्क्रिप्ट में कहा जाता है। फिर, मैं बस प्रत्येक परिभाषित वैश्विक संस्करण के लिए एक्सेसर विधि बनाता हूं। मुझे आशा है कि मैं इसे कई बार बढ़ा सकता हूं! धन्यवाद पीटर!
स्वदेव १

1
क्या होगा अगर कई वैश्विक चर हैं और मैं वैश्विक वक्तव्य के बाद उन्हें एक-एक करके सूचीबद्ध नहीं करना चाहता हूं?
jtlz2

23

आपको हर उस फ़ंक्शन में वैश्विक चर का संदर्भ देना होगा जिसका आप उपयोग करना चाहते हैं।

निम्नलिखित नुसार:

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
'हर फंक्शन जिसे आप उपयोग करना चाहते हैं' सूक्ष्म रूप से गलत है, हर फंक्शन में पास होना चाहिए: 'जहां आप अपडेट करना चाहते हैं '
spazm

21

आप वास्तव में वैश्विक को स्थानीय चर में संग्रहीत नहीं कर रहे हैं, बस उसी वस्तु का स्थानीय संदर्भ बना रहे हैं जो आपके मूल वैश्विक संदर्भ को संदर्भित करता है। याद रखें कि पायथन में सब कुछ एक वस्तु का जिक्र करने वाला नाम है, और कुछ भी सामान्य ऑपरेशन में कॉपी नहीं किया जाता है।

यदि किसी पहचानकर्ता को पूर्वनिर्धारित वैश्विक को संदर्भित करने के लिए आपको स्पष्ट रूप से निर्दिष्ट नहीं करना था, तो संभवतः आपको स्पष्ट रूप से यह बताना होगा कि कोई पहचानकर्ता इसके बजाय एक नया स्थानीय चर है (उदाहरण के लिए, 'var' कमांड जैसी कोई चीज़। जावास्क्रिप्ट में देखा)। चूंकि स्थानीय चर किसी भी गंभीर और गैर-तुच्छ प्रणाली में वैश्विक चर की तुलना में अधिक सामान्य हैं, पाइथन की प्रणाली ज्यादातर मामलों में अधिक समझ में आती है।

आपके पास ऐसी भाषा हो सकती है जो अनुमान लगाने का प्रयास करती हो, यदि वह मौजूद नहीं है या अगर वह मौजूद नहीं है तो एक स्थानीय चर का निर्माण कर सकती है। हालाँकि, यह बहुत त्रुटि वाला होगा। उदाहरण के लिए, किसी अन्य मॉड्यूल का आयात करना अनजाने में आपके प्रोग्राम के व्यवहार को बदलकर, उस नाम से एक वैश्विक चर पेश कर सकता है।




14

निम्नलिखित पर और एक ऐड के रूप में, सभी वैश्विक चर को स्थानीय रूप से घोषित करने के लिए एक फ़ाइल का उपयोग करें import as :

फ़ाइल initval.py :

Stocksin = 300
Prices = []

फ़ाइल getstocks.py :

import initval as iv

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


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

1
वैश्विक चर को दूसरी फ़ाइल में स्थानांतरित करने का क्या लाभ है? यह सिर्फ एक छोटे फ़ाइल में वैश्विक चर समूह के साथ है? और कथन का उपयोग क्यों import ... as ...? सिर्फ क्यों नहीं import ...?
ओलिबर

1
आह ... मैं आखिरकार लाभ को समझ गया हूं: कीवर्ड का उपयोग करने की कोई आवश्यकता नहीं है global:-) => +1 :-) कृपया इन प्रश्नों को स्पष्ट करने के लिए अपना उत्तर संपादित करें जो अन्य लोगों के पास भी हो सकते हैं। चीयर्स
ओलिव्रे

13

एक वैश्विक सरणी के स्पष्ट तत्वों को लिखने के लिए स्पष्ट रूप से वैश्विक घोषणा की आवश्यकता नहीं है, हालांकि इसे "थोक" में लिखने की आवश्यकता है:

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

मैं इसे जोड़ रहा हूं क्योंकि मैंने इसे किसी भी अन्य उत्तर में नहीं देखा है और यह किसी ऐसे ही व्यक्ति के साथ संघर्ष करने के लिए उपयोगी हो सकता है। globals()समारोह एक परिवर्तनशील वैश्विक प्रतीक शब्दकोश रिटर्न जहां आप कर सकते हैं "जादुई" मेक अपने कोड के बाकी के लिए उपलब्ध डेटा। उदाहरण के लिए:

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

तथा

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

क्या आप केवल वैश्विक नाम स्थान में से चर को डंप / लोड करेंगे। सुपर सुविधाजनक, कोई उपद्रव, कोई उपद्रव नहीं। बहुत यकीन है कि यह केवल पायथन 3 है।


3
globals()हमेशा स्थानीय संदर्भ में उपलब्ध ग्लोबल्स को लौटाता है, इसलिए यहां एक उत्परिवर्तन दूसरे मॉड्यूल में प्रतिबिंबित नहीं हो सकता है।
किरण जोनलगड्डा

6

उस श्रेणी के नामस्थान का संदर्भ दें जहाँ आप परिवर्तन दिखाना चाहते हैं।

इस उदाहरण में, फ़ाइल कॉन्फ़िगरेशन से रनर अधिकतम उपयोग कर रहा है । मैं चाहता हूं कि जब रनर इसका उपयोग कर रहा हो तो अधिकतम के मूल्य को बदलने के लिए मेरा परीक्षण ।

मुख्य / config.py

max = 15000

मुख्य / runner.py

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

परीक्षण / 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

ग्लोबल्स ठीक हैं - मल्टीप्रोसेसिंग के अलावा

अलग-अलग प्लेटफॉर्म पर मल्टीप्रोसेसिंग के सिलसिले में ग्लोबल्स एक तरफ विंडोज / मैक ओएस के रूप में और दूसरी तरफ लिनक्स परेशान करने वाले हैं।

मैं आपको एक सरल उदाहरण के साथ यह दिखाऊंगा कि एक समस्या है जो मैं कुछ समय पहले चला रहा हूं।

यदि आप समझना चाहते हैं, तो विंडोज / मैकओ और लिनक्स पर चीजें अलग-अलग क्यों हैं, तो आपको यह जानना होगा कि, एक नई प्रक्रिया शुरू करने के लिए डिफ़ॉल्ट तंत्र ...

  • Windows / MacO 'स्पॉन' है
  • लिनक्स 'कांटा' है

वे मेमोरी आबंटन में भिन्न हैं एक आरंभीकरण ... (लेकिन मैं यहां नहीं जाता हूं)।

आइए नजर डालते हैं समस्या / उदाहरण पर ...

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)

खिड़कियाँ

यदि आप इसे विंडोज पर चलाते हैं (और मुझे मैकओएस पर भी लगता है), तो आपको निम्न आउटपुट मिलते हैं ...

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

लिनक्स

यदि आप इसे लिनक्स पर चलाते हैं, तो आपको इसके बजाय निम्नलिखित मिलते हैं।

task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.