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




global-variables scope (15)

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

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


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

फ़ाइल initval.py

Stocksin = 300
Prices = []

फ़ाइल getstocks.py

import  initval as  iv

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


Def getmycharts ():
    For ic in range (0,iv.Stocksin):

.....


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

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]

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

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

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

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


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

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

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

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

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

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

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

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


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

मान लें कि आपके पास एक मॉड्यूल है:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

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

def func1():
    global myGlobal
    myGlobal = 42

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

जब आप myGlobal नाम के लिए 42 असाइन करते हैं, इसलिए, पायथन एक स्थानीय चर बनाता है जो समान नाम के वैश्विक चर को छाया करता है। वह स्थानीय गुंजाइश से बाहर हो जाता है और garbage-collected जब func1() लौटाता है; इस बीच, func2() कभी भी (unmodified) वैश्विक नाम के अलावा कुछ भी नहीं देख सकता है। ध्यान दें कि यह नेमस्पेस निर्णय संकलन समय पर होता है, न कि रनटाइम पर - यदि आप इसे निर्दिष्ट करने से पहले func1() अंदर func1() के मान को पढ़ना चाहते थे, तो आपको एक UnboundLocalError मिल UnboundLocalError , क्योंकि पायथन ने पहले से ही यह तय कर लिया है कि यह होना चाहिए एक स्थानीय चर है लेकिन इसका अभी तक कोई मूल्य नहीं है। लेकिन ' 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        
>>> 

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


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

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

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


आप जो कह रहे हैं वह इस तरह की विधि का उपयोग करना है:

globvar = 5

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

f()  # Prints 5

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

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

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


कक्षा नामस्थान का संदर्भ लें जहां आप परिवर्तन दिखाना चाहते हैं।

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

मुख्य / 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()

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

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

ग्लोबल-इन-ए-मॉड्यूल का एक विशिष्ट उपयोग यहां वर्णित किया गया है - how-do-i-share-global-variables-across-modules , और पूर्णता के लिए सामग्री यहां साझा की जाती है:

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

फ़ाइल: config.py

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

फ़ाइल: mod.py

import config
config.x = 1

फ़ाइल: main.py

import config
import mod
print config.x

इसे इस्तेमाल करे:

def x1():
    global x
    x = 6

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

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

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

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 है।


आप इसे लागू करने वाले प्रत्येक फ़ंक्शन में इसे 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 कीवर्ड की स्पष्ट रूप से आवश्यकता के साथ क्या खेल रहे हैं।

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


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

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

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


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

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




scope