स्कूपिंग नियमों का संक्षिप्त विवरण?


472

क्या वास्तव में अजगर scoping नियम हैं?

अगर मेरे पास कुछ कोड है:

code1
class Foo:
   code2
   def spam.....
      code3
      for code4..:
       code5
       x()

कहाँ है x पाया है? कुछ संभावित विकल्पों में नीचे दी गई सूची शामिल है:

  1. संलग्नक स्रोत फ़ाइल में
  2. वर्ग नामस्थान में
  3. फ़ंक्शन परिभाषा में
  4. लूप इंडेक्स चर के लिए
  5. लूप के अंदर

निष्पादन के दौरान भी संदर्भ होता है, जब फ़ंक्शन spamको कहीं और पारित किया जाता है। और शायद लंबोदर कार्य करता है थोड़ा अलग तरीके से पास हों?

कहीं एक साधारण संदर्भ या एल्गोरिथ्म होना चाहिए। यह मध्यवर्ती पायथन प्रोग्रामर्स के लिए एक भ्रामक दुनिया है।


2
स्कोपिंग नियमों को काफी प्रतिकूल रूप से वर्णित किया गया है - लेकिन यह भी पूरी तरह से - पायथन प्रलेखन में: docs.python.org/3/reference/…
jefe2000

जवाबों:


420

असल में, लर्निंग पाइथन, 3 से पायथन स्कोप संकल्प के लिए एक संक्षिप्त नियम ईडी। । (ये नियम चर नामों के लिए विशिष्ट हैं, विशेषता नहीं। यदि आप इसे बिना अवधि के संदर्भित करते हैं, तो ये नियम लागू होते हैं।)

लेगब नियम

  • L ocal - नाम किसी फ़ंक्शन ( defया lambda) के भीतर किसी भी तरह से असाइन किया गया है , और उस फ़ंक्शन में वैश्विक घोषित नहीं किया गया है

  • E nclosing-function - किसी भी और सभी के सांविधिक रूप से संलग्न कार्यों ( defया lambda) के स्थानीय दायरे में , आंतरिक से बाहरी के लिए नामित नाम

  • जी लोबाल (मॉड्यूल) - एक मॉड्यूल फ़ाइल के शीर्ष-स्तर पर निर्दिष्ट नाम, या फ़ाइल के भीतर एक globalस्टेटमेंट निष्पादित करकेdef

  • बी uilt-इन (अजगर) - नाम में पहले ही असाइन कर निर्मित नाम मॉड्यूल: open, range,SyntaxError , आदि

तो, के मामले में

code1
class Foo:
    code2
    def spam():
        code3
        for code4:
            code5
            x()

forपाश अपने स्वयं के नाम स्थान नहीं है। लेगबी ऑर्डर में, स्कोप होंगे

  • L: स्थानीय में def spam(a)code3 , code4और code5)
  • ई: कोई भी संलग्न कार्य (यदि पूरा उदाहरण दूसरे में हो तो) def )
  • जी: xमॉड्यूल में विश्व स्तर पर घोषित किए गए थेcode1 ) ?
  • बी: xपायथन में कोई भी बिलिन ।

xकभी नहीं मिलेगा code2(यहां तक ​​कि उन मामलों में जहां आप उम्मीद कर सकते हैं, एंट्टी का जवाब या यहां देखें )।


45
वैश्विक पहुंच के लिए एक चेतावनी के रूप में - एक वैश्विक चर को पढ़ना स्पष्ट घोषणा के बिना हो सकता है, लेकिन वैश्विक (var_name) घोषित किए बिना इसे लिखना एक नया स्थानीय उदाहरण बनाएगा।
पीटर गिब्सन

12
वास्तव में @Peter, global(var_name)वाक्यात्मक रूप से गलत है। सही सिंटैक्स global var_nameकोष्ठक के बिना होगा । हालांकि आपके पास एक वैध बिंदु है।
मार्टीन्यू

यदि ऐसा है, तो नीचे "बार" के लिए फू का "y" वैरिएबल क्यों नहीं दिखाई दे रहा है: >>> def foo(x): ... y = x ... def bar(z): ... y = z ... bar(5) ... print x,y ... >>> foo(3) 3 3
जोनाथन मेयर

3
@ जोनाथन: क्योंकि प्रत्येक yको लिखा जा रहा है और कोई global yघोषणा नहीं है - देखें @ पीटर की टिप्पणी।
मार्टिउ

@ लक्ष्मणप्रसाद यह "ई" में आता है, लेकिन इसका एक विशेष व्यवहार है जो ध्यान देने योग्य है: यह एक वर्ग चर है, इसलिए यह वस्तुओं के बीच एक "वैश्विक" है। यदि आप जानते हैं कि आप क्या कर रहे हैं, तो इसे निरूपित करने से अनपेक्षित और कठिन डिबग मुद्दों को जन्म मिलेगा
Ctrl-C

157

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

आपके उदाहरण में केवल 3 स्कोप हैं जहां x को खोजा जाएगा:

  • स्पैम का दायरा - जिसमें कोड 3 और कोड 5 (साथ ही कोड 4, आपका लूप वेरिएबल) में परिभाषित सब कुछ शामिल है

  • वैश्विक क्षेत्र - सब कुछ कोड 1 में परिभाषित है, साथ ही फू (और इसके बाद जो भी परिवर्तन होता है)

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

अधिक स्कोप केवल तब दिखाई देते हैं जब आप चित्र में नेस्टेड फ़ंक्शन (या लैम्ब्डा) का परिचय देते हैं। हालांकि आप अपेक्षा के अनुसार बहुत अधिक व्यवहार करेंगे। नेस्टेड फ़ंक्शन स्थानीय दायरे में सब कुछ एक्सेस कर सकता है, साथ ही एन्कोडिंग फ़ंक्शन के दायरे में कुछ भी। जैसे।

def foo():
    x=4
    def bar():
        print x  # Accesses x from foo's scope
    bar()  # Prints 4
    x=5
    bar()  # Prints 5

प्रतिबंध:

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

global_var1 = []
global_var2 = 1

def func():
    # This is OK: It's just accessing, not rebinding
    global_var1.append(4) 

    # This won't affect global_var2. Instead it creates a new variable
    global_var2 = 2 

    local1 = 4
    def embedded_func():
        # Again, this doen't affect func's local1 variable.  It creates a 
        # new local variable also called local1 instead.
        local1 = 5
        print local1

    embedded_func() # Prints 5
    print local1    # Prints 4

वास्तव में एक फ़ंक्शन स्कोप के भीतर से वैश्विक चर के बाइंडिंग को संशोधित करने के लिए, आपको यह निर्दिष्ट करने की आवश्यकता है कि वैरिएबल वैश्विक कीवर्ड के साथ वैश्विक है। उदाहरण के लिए:

global_var = 4
def change_global():
    global global_var
    global_var = global_var + 1

वर्तमान में फंक्शन स्कोप्स को घेरने में वैरिएबल के लिए ऐसा करने का कोई तरीका नहीं है , लेकिन पायथन 3 एक नए कीवर्ड का परिचय देता है, " nonlocal" जो ग्लोबल के समान ही कार्य करेगा, लेकिन नेस्टेड फंक्शन स्कोप के लिए।


111

पायथन 3 समय के संबंध में कोई गहन उत्तर नहीं था, इसलिए मैंने यहां एक उत्तर दिया। यहाँ जो कुछ वर्णित किया गया है, उनमें से अधिकांश पायथन 3 प्रलेखन के नामों के 4.2.2 संकल्प में विस्तृत है ।

जैसा कि अन्य उत्तरों में प्रदान किया गया है, स्थानीय, एनक्लोजिंग, ग्लोबल और बिलिन के लिए 4 मूल स्कोप, लेगबी हैं। उन लोगों के अलावा, एक विशेष गुंजाइश है, वर्ग निकाय , जिसमें कक्षा के भीतर परिभाषित तरीकों के लिए एक संलग्न गुंजाइश शामिल नहीं है; क्लास बॉडी के भीतर कोई भी असाइनमेंट वहाँ से वेरिएबल को बॉडी बॉन्ड में बांधा जाता है।

विशेष रूप से, कोई ब्लॉक स्टेटमेंट, इसके अलावा defऔर class, एक वैरिएबल स्कोप बनाएँ। पायथन 2 में एक सूची बोध एक चर गुंजाइश नहीं बनाता है, हालांकि पायथन 3 में सूची समझ के भीतर लूप चर एक नए दायरे में बनाया गया है।

वर्ग निकाय की विशिष्टताओं को प्रदर्शित करने के लिए

x = 0
class X(object):
    y = x
    x = x + 1 # x is now a variable
    z = x

    def method(self):
        print(self.x) # -> 1
        print(x)      # -> 0, the global x
        print(y)      # -> NameError: global name 'y' is not defined

inst = X()
print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)

इस प्रकार फंक्शन बॉडी के विपरीत, आप वैरिएबल को उसी नाम से वर्ग बॉडी में फिर से असाइन कर सकते हैं, उसी नाम के साथ क्लास वेरिएबल प्राप्त करने के लिए; इस नाम पर आगे के लुकअप इसके बजाय क्लास वेरिएबल के लिए हल करते हैं।


पायथन के कई नए लोगों के लिए एक बड़ा आश्चर्य यह है कि एक forलूप एक वैरिएबल स्कोप नहीं बनाता है। पायथन 2 में सूची की समझ या तो गुंजाइश नहीं बनाती है (जबकि जनरेटर और तानाशाह समझ भी करते हैं!) इसके बजाय वे फ़ंक्शन या वैश्विक दायरे में मूल्य को लीक करते हैं:

>>> [ i for i in range(5) ]
>>> i
4

बोधगम्य का उपयोग एक चालाक (या भयानक के रूप में किया जा सकता है) यदि आप पाइथन 2 में लैम्ब्डा अभिव्यक्ति के भीतर परिवर्तनीय वैरिएबल बनाने का तरीका करते हैं - एक लैम्ब्डा अभिव्यक्ति एक वैरिएबल स्कोप बनाता है, जैसे कि def स्टेटमेंट होगा, लेकिन नंबा के भीतर किसी भी स्टेटमेंट की अनुमति नहीं है। पायथन में एक बयान होने का मतलब है कि लंबोदर में कोई भी चर असाइनमेंट की अनुमति नहीं है, लेकिन एक सूची एक अभिव्यक्ति ...

पायथन 3 में यह व्यवहार तय किया गया है - कोई भी अभिव्यक्ति के भाव या जनरेटर रिसाव चर नहीं हैं।


वैश्विक वास्तव में मॉड्यूल गुंजाइश का मतलब है; मुख्य अजगर मॉड्यूल है __main__; सभी आयातित मॉड्यूल sys.modulesचर के माध्यम से सुलभ हैं ; उपयोग करने के लिए उपयोग करने के __main__लिए sys.modules['__main__'], या import __main__; यह पूरी तरह से वहाँ की विशेषताओं तक पहुँचने और असाइन करने के लिए स्वीकार्य है; वे मुख्य मॉड्यूल के वैश्विक दायरे में चर के रूप में दिखाई देंगे।


यदि किसी नाम को कभी भी मौजूदा दायरे में (वर्ग के दायरे को छोड़कर) सौंपा गया है, तो उसे उस दायरे से संबंधित माना जाएगा, अन्यथा इसे किसी भी संलग्न दायरे से संबंधित माना जाएगा जो चर को असाइन करता है (यह असाइन नहीं किया जा सकता है) अभी तक, या नहीं), या अंत में वैश्विक गुंजाइश। यदि चर को स्थानीय माना जाता है, लेकिन इसे अभी तक सेट नहीं किया गया है, या हटा दिया गया है, तो चर मान को पढ़ने से परिणाम होगा UnboundLocalError, जो एक उपवर्ग है NameError

x = 5
def foobar():
    print(x)  # causes UnboundLocalError!
    x += 1    # because assignment here makes x a local variable within the function

# call the function
foobar()

गुंजाइश यह घोषित कर सकती है कि वह वैश्विक कीवर्ड के साथ वैश्विक (मॉड्यूल स्कोप) चर को संशोधित करना चाहती है:

x = 5
def foobar():
    global x
    print(x)
    x += 1

foobar() # -> 5
print(x) # -> 6

यह भी संभव है, भले ही इसे परिक्षेत्र के दायरे में छाया हुआ हो:

x = 5
y = 13
def make_closure():
    x = 42
    y = 911
    def func():
        global x # sees the global value
        print(x, y)
        x += 1

    return func

func = make_closure()
func()      # -> 5 911
print(x, y) # -> 6 13

अजगर 2 में एनक्लोजिंग दायरे में मूल्य को संशोधित करने का कोई आसान तरीका नहीं है; आमतौर पर यह एक परिवर्तनशील मूल्य होने पर नकली होता है, जैसे कि 1 की लंबाई वाली सूची:

def make_closure():
    value = [0]
    def get_next_value():
        value[0] += 1
        return value[0]

    return get_next_value

get_next = make_closure()
print(get_next()) # -> 1
print(get_next()) # -> 2

हालांकि अजगर 3 में, nonlocalबचाव के लिए आता है:

def make_closure():
    value = 0
    def get_next_value():
        nonlocal value
        value += 1
        return value
    return get_next_value

get_next = make_closure() # identical behavior to the previous example.

nonlocalप्रलेखन का कहना है कि

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

यानी nonlocalहमेशा अंतरतम बाहरी गैर-वैश्विक गुंजाइश को संदर्भित करता है जहां नाम को बाध्य किया गया है (यानी असाइन किया गया है, जिसमें forलक्ष्य चर के रूप में उपयोग किया जाता है , withखंड में, या फ़ंक्शन पैरामीटर के रूप में)।


कोई भी वैरिएबल जिसे वर्तमान स्कोप के लिए स्थानीय नहीं माना जाता है, या कोई भी स्कोपिंग स्कोप, एक ग्लोबल वैरिएबल है। मॉड्यूल वैश्विक शब्दकोश में एक वैश्विक नाम देखा जाता है; यदि नहीं मिला है, तो वैश्विक निर्मित मॉड्यूल से देखा जाता है; मॉड्यूल का नाम अजगर 2 से अजगर 3 में बदल दिया गया था; अजगर 2 में यह था __builtin__और अजगर 3 में इसे अब कहा जाता है builtins। यदि आप निर्मित मॉड्यूल की एक विशेषता को असाइन करते हैं, तो यह किसी भी मॉड्यूल के लिए एक पठनीय वैश्विक चर के रूप में दिखाई देगा, जब तक कि मॉड्यूल उन्हें उसी नाम के साथ अपने स्वयं के वैश्विक चर के साथ छाया नहीं देता।


अंतर्निहित मॉड्यूल पढ़ना भी उपयोगी हो सकता है; मान लें कि आप फ़ाइल के कुछ हिस्सों में अजगर 3 स्टाइल प्रिंट फ़ंक्शन चाहते हैं, लेकिन फ़ाइल के अन्य हिस्से अभी भी printस्टेटमेंट का उपयोग करते हैं । पायथन 2.6-2.7 में आप पायथन 3 printफ़ंक्शन को पकड़ सकते हैं :

import __builtin__

print3 = __builtin__.__dict__['print']

from __future__ import print_functionवास्तव में आयात नहीं करता है printअजगर 2 में समारोह कहीं भी - के बजाय यह सिर्फ के लिए पार्स करने के नियमों को निष्क्रिय printवर्तमान मॉड्यूल में बयान, हैंडलिंग printकिसी अन्य चर पहचानकर्ता की तरह, और इस तरह की इजाजत दी printसमारोह builtins में देखा जा।


23

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

संपादित करें: यहां पीईपी इस बारे में अधिक जानकारी के साथ है।


23

स्कोप का थोड़ा और पूर्ण उदाहरण:

from __future__ import print_function  # for python 2 support

x = 100
print("1. Global x:", x)
class Test(object):
    y = x
    print("2. Enclosed y:", y)
    x = x + 1
    print("3. Enclosed x:", x)

    def method(self):
        print("4. Enclosed self.x", self.x)
        print("5. Global x", x)
        try:
            print(y)
        except NameError as e:
            print("6.", e)

    def method_local_ref(self):
        try:
            print(x)
        except UnboundLocalError as e:
            print("7.", e)
        x = 200 # causing 7 because has same name
        print("8. Local x", x)

inst = Test()
inst.method()
inst.method_local_ref()

उत्पादन:

1. Global x: 100
2. Enclosed y: 100
3. Enclosed x: 101
4. Enclosed self.x 101
5. Global x 100
6. global name 'y' is not defined
7. local variable 'x' referenced before assignment
8. Local x 200

6
यह बहुत अच्छा जवाब है। हालांकि, मुझे लगता है कि के बीच मतभेद methodऔर method_local_refप्रकाश डाला जाना चाहिए। methodवैश्विक वैरिएबल तक पहुँचने और इसे प्रिंट करने में सक्षम है 5. Global x। लेकिन method_local_refऐसा नहीं हो सकता क्योंकि बाद में यह उसी नाम से एक स्थानीय चर को परिभाषित करता है। आप x = 200लाइन को हटाकर इसका परीक्षण कर सकते हैं और अंतर देख सकते हैं
kiril

@ ब्रायन्रे: जेड के बारे में क्या?
मलिक ए। रूमी

@ मिर्किल I ने उस बारे में एक नोट जोड़ा
ब्रायन्रे

@ MalikA.Rumi मैंने z को हटा दिया क्योंकि यह दिलचस्प नहीं था
बजे

हैरानी की बात यह है कि पायथन स्कोप की यह एकमात्र स्पष्ट व्याख्या है, जो मुझे एसओ के सभी पर मिल सकती है। बस एक बहुत ही बुनियादी उदाहरण का उपयोग कर। धन्यवाद!
not2qubit

13

पायथन आपके चरों को आम तौर पर उपलब्ध तीन नामस्थानों के साथ हल करता है।

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

दो कार्य हैं: globalsऔर localsजो आपको इन दो नामस्थानों की सामग्री दिखाते हैं।

नाम स्थान पैकेज, मॉड्यूल, कक्षाएं, ऑब्जेक्ट निर्माण और कार्यों द्वारा बनाए जाते हैं। नामस्थानों के कोई अन्य स्वाद नहीं हैं।

इस स्थिति में, किसी फ़ंक्शन को कॉल करने के xलिए स्थानीय नाम स्थान या वैश्विक नाम स्थान में हल करना होगा।

इस मामले में स्थानीय, विधि फ़ंक्शन का शरीर है Foo.spam

ग्लोबल है - वेल - ग्लोबल।

नियम विधि कार्यों (और नेस्टेड फ़ंक्शन परिभाषाओं) द्वारा बनाए गए नेस्टेड स्थानीय रिक्त स्थान की खोज करना है, फिर वैश्विक खोज करें। बस।

कोई और स्कोप नहीं है। forबयान (और जैसे अन्य यौगिक बयानों ifऔरtry ) नई नेस्टेड स्कोप नहीं बनाते हैं। केवल परिभाषाएँ (पैकेज, मॉड्यूल, फ़ंक्शंस, कक्षाएं और ऑब्जेक्ट इंस्टेंस।)

एक वर्ग परिभाषा के अंदर, नाम वर्ग नाम स्थान का हिस्सा हैं। code2, उदाहरण के लिए, वर्ग के नाम से योग्य होना चाहिए। आम तौर पर Foo.code2। हालांकि, self.code2यह भी काम करेगा क्योंकि पायथन ऑब्जेक्ट्स क्लास को एक गिरावट के रूप में देखते हैं।

ऑब्जेक्ट (किसी वर्ग का उदाहरण) के उदाहरण चर हैं। ये नाम ऑब्जेक्ट के नेमस्पेस में हैं। उन्हें वस्तु द्वारा योग्य होना चाहिए। ( variable.instance)

एक क्लास पद्धति के भीतर, आपके पास स्थानीय और ग्लोबल्स हैं। आप self.variableउदाहरण को नामस्थान के रूप में लेने के लिए कहते हैं । आप ध्यान देंगे कि selfयह हर वर्ग के सदस्य के लिए एक तर्क है, जो इसे स्थानीय नामस्थान का हिस्सा बनाता है।

देखें अजगर स्कोप नियम , अजगर स्कोप , चर का दायरा


5
यह पुराना हो चुका है। चूंकि 2.1 (7 साल पहले) दो से अधिक स्कोप हैं, क्योंकि नेस्टेड फ़ंक्शंस नए स्कोप पेश करते हैं, इसलिए एक फ़ंक्शन के भीतर एक फ़ंक्शन को इसके स्थानीय दायरे, एन्क्लोज़िंग फ़ंक्शंस स्कोप, और ग्लोबल स्कोप (भी बिल्डिन्स) तक पहुंच होगी।
ब्रायन

मुझे खेद है, अब ऐसा नहीं है। Python has two namespaces available. Global and local-to-something.
रिजवान कासिम

9

X कहां पाया जाता है?

x नहीं मिला क्योंकि आपने इसे परिभाषित नहीं किया है। :-) यदि आप इसे वहां रखते हैं तो कोड 1 (वैश्विक) या कोड 3 (स्थानीय) में पाया जा सकता है।

code2 (वर्ग के सदस्य) समान वर्ग के तरीकों के अंदर कोड करने के लिए दृश्यमान नहीं हैं - आप आमतौर पर स्वयं का उपयोग करके उन्हें एक्सेस करेंगे। कोड 4 / कोड 5 (लूप्स) कोड 3 के समान स्कोप में रहते हैं, इसलिए यदि आपने वहां x लिखा है तो आप कोड 3 में परिभाषित एक्स उदाहरण को बदल देंगे, नया एक्स नहीं बना रहे।

पायथन सांख्यिकीय रूप से स्कूप किया गया है, इसलिए यदि आप किसी अन्य फ़ंक्शन के लिए 'स्पैम' पास करते हैं, तो स्पैम में अभी भी मॉड्यूल में ग्लोबल्स तक पहुंच होगी (यह कोड 1 में परिभाषित किया गया है), और कोई भी अन्य स्कोप (नीचे देखें)। कोड 2 सदस्यों को फिर से स्वयं के माध्यम से एक्सेस किया जाएगा।

लाम्बा को हराना अलग नहीं है। यदि आपके पास एक फ़ंक्शन के अंदर उपयोग किया गया लैम्बडा है, तो यह नेस्टेड फ़ंक्शन को परिभाषित करने के समान है। पायथन 2.2 में, नेस्टेड स्कोप उपलब्ध हैं। इस मामले में आप x को किसी भी स्तर पर फ़ंक्शन नेस्टिंग से बाँध सकते हैं और पायथन सबसे अंतरतम उदाहरण उठाएगा:

x= 0
def fun1():
    x= 1
    def fun2():
        x= 2
        def fun3():
            return x
        return fun3()
    return fun2()
print fun1(), x

2 0

fun3 निकटतम x स्कोप से आवृत्ति x को देखता है, जो फन 2 से जुड़ा फंक्शन स्कोप है। लेकिन फ़न 1 और विश्व स्तर पर परिभाषित अन्य एक्स इंस्टेंस प्रभावित नहीं होते हैं।

नेस्टेड_कैप्स से पहले - पायथन में 2.1 और प्री 2.1 में, जब तक कि आप विशेष रूप से फ्यूचर-इंपोर्ट-फन 1 का उपयोग करके फ़ीचर नहीं मांगते हैं - fun1 और fun2 के स्कोप्स fun3 के लिए दिखाई नहीं देते हैं, इसलिए S.Lott का जवाब है और आपको ग्लोबल x मिलेगा :

0 0

1

पायथन में,

कोई भी चर जिसे एक मान दिया जाता है वह उस ब्लॉक के लिए स्थानीय होता है जिसमें असाइनमेंट दिखाई देता है।

यदि कोई चर वर्तमान दायरे में नहीं पाया जा सकता है, तो कृपया लेग ऑर्डर को देखें।

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