खोज…


वाक्य - विन्यास

  • वैश्विक ए, बी, सी
  • nonlocal a, b
  • x = कुछ # x बांधता है
  • (x, y) = कुछ # x और y को बांधता है
  • x + = कुछ # x बांधता है। इसी तरह अन्य सभी "op =" के लिए
  • डेल एक्स # बाइंड्स एक्स
  • किसी चीज़ में x के लिए: # x को बांधता है
  • x के साथ कुछ के साथ: # x को बांधता है
  • अपवाद को छोड़कर पूर्व के रूप में: # ब्लॉक के अंदर पूर्व बांधता है

सार्वत्रिक चर

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

x = 'Hi'

def read_x():
    print(x)   # x is just referenced, therefore assumed global

read_x()       # prints Hi

def read_y():
    print(y)   # here y is just referenced, therefore assumed global

read_y()       # NameError: global name 'y' is not defined

def read_y():
    y = 'Hey'  # y appears in an assignment, therefore it's local
    print(y)   # will find the local y

read_y()       # prints Hey

def read_x_local_fail():
    if False:
        x = 'Hey'  # x appears in an assignment, therefore it's local
    print(x)   # will look for the _local_ z, which is not assigned, and will not be found

read_x_local_fail()   # UnboundLocalError: local variable 'x' referenced before assignment

आम तौर पर, एक कार्यक्षेत्र के अंदर एक असाइनमेंट समान नाम के किसी भी बाहरी चर को छाया देगा:

x = 'Hi'

def change_local_x():
    x = 'Bye'
    print(x)
change_local_x()  # prints Bye
print(x)  # prints Hi

एक नाम global घोषित करने का मतलब है कि, बाकी गुंजाइश के लिए, नाम के लिए कोई भी असाइनमेंट मॉड्यूल के शीर्ष स्तर पर होगा:

x = 'Hi'

def change_global_x():
    global x
    x = 'Bye'
    print(x)

change_global_x()  # prints Bye
print(x)  # prints Bye

global कीवर्ड का अर्थ है कि असाइनमेंट मॉड्यूल के शीर्ष स्तर पर होगा, कार्यक्रम के शीर्ष स्तर पर नहीं। अन्य मॉड्यूल को अभी भी मॉड्यूल के भीतर चर की सामान्य डॉटेड पहुंच की आवश्यकता होगी।

सारांशित करने के लिए: यह जानने के लिए कि क्या चर x किसी फ़ंक्शन के लिए स्थानीय है, आपको पूरे फ़ंक्शन को पढ़ना चाहिए:

  1. यदि आपने global x पाया है, तो x एक वैश्विक चर है
  2. यदि आपने nonlocal x पाया है, तो x एक एनक्लोजिंग फ़ंक्शन के अंतर्गत आता है, और न तो स्थानीय और न ही वैश्विक है
  3. यदि आपने x = 5 या for x in range(3) या किसी अन्य बंधन में पाया है, तो x एक स्थानीय चर है
  4. अन्यथा x कुछ एनक्लोजिंग स्कोप (फ़ंक्शन स्कोप, ग्लोबल स्कोप या बिलिन) के अंतर्गत आता है

स्थानीय चर

एक नाम एक समारोह के अंदर ही है, तो यह डिफ़ॉल्ट केवल समारोह में ऐक्सेस कर रहा है:

def foo():
    a = 5
    print(a) # ok

print(a) #  NameError: name 'a' is not defined

नियंत्रण प्रवाह निर्माण का दायरा (अपवाद को except ) पर कोई प्रभाव नहीं पड़ता है, लेकिन चर को एक्सेस करना जो अभी तक असाइन नहीं किया गया है, एक त्रुटि है:

def foo():
    if True: 
        a = 5
    print(a) # ok

b = 3
def bar():
    if False:
        b = 5
    print(b) # UnboundLocalError: local variable 'b' referenced before assignment

आम बाध्यकारी संचालन कार्य, कर रहे हैं for इस तरह के रूप छोरों, और संवर्धित कार्य a += 5

नॉनोकॉकल वेरिएबल्स

अजगर 3.x 3.0

पायथन 3 ने एक नया कीवर्ड जोड़ा, जिसे नॉनक्लॉक कहा जाता है। नॉनक्लॉक कीवर्ड आंतरिक दायरे में एक ओवरराइड जोड़ता है। आप इसके बारे में पीईपी 3104 में पढ़ सकते हैं। यह कोड उदाहरण के एक जोड़े के साथ सबसे अच्छा सचित्र है। सबसे आम उदाहरणों में से एक कार्य है कि वेतन वृद्धि कर सकते हैं:

def counter():
    num = 0
    def incrementer():
        num += 1
        return num
    return incrementer

आप इस कोड को चलाने की कोशिश करें, तो आप एक UnboundLocalError क्योंकि संख्या चर से पहले ही अंतरतम समारोह में असाइन किया गया है संदर्भित है प्राप्त होगा। आइए मिश्रण में नॉनकॉक जोड़ें:

def counter():
    num = 0
    def incrementer():
        nonlocal num
        num += 1
        return num
    return incrementer

c = counter()
c() # = 1
c() # = 2
c() # = 3

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

(ध्यान दें कि यहां प्रस्तुत कार्यक्षमता जनरेटर का उपयोग करके बेहतर तरीके से लागू की गई है।)

बाइंडिंग घटना

x = 5
x += 7
for x in iterable: pass    

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

नाम देखते समय फ़ंक्शंस क्लास स्कोप को छोड़ देते हैं

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

a = 'global'

class Fred:
    a = 'class'  # class scope
    b = (a for i in range(10))  # function scope
    c = [a for i in range(10)]  # function scope
    d = a  # class scope
    e = lambda: a  # function scope
    f = lambda a=a: a  # default argument uses class scope
    
    @staticmethod  # or @classmethod, or regular instance method
    def g():  # function scope
        return a

print(Fred.a)  # class
print(next(Fred.b))  # global
print(Fred.c[0])  # class in Python 2, global in Python 3
print(Fred.d)  # class
print(Fred.e())  # global
print(Fred.f())  # class
print(Fred.g()) # global

उपयोगकर्ता इस class काम से अपरिचित हैं जो class प्रिंट करने के लिए b , c , और e अपेक्षा कर सकता है।


पीईपी 227 से :

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

नामकरण और बंधन पर पायथन के दस्तावेज से:

एक वर्ग ब्लॉक में परिभाषित नामों का दायरा वर्ग ब्लॉक तक सीमित है; यह विधियों के कोड ब्लॉकों तक नहीं फैलता है - इसमें एक कार्यक्षेत्र का उपयोग करके लागू किए जाने के बाद से समझ और जनरेटर अभिव्यक्तियाँ शामिल हैं। इसका मतलब है कि निम्नलिखित विफल हो जाएगा:

class A:
    a = 42
    b = list(a + i for i in range(10))

यह उदाहरण मार्टिज़न पीटर के इस उत्तर के संदर्भों का उपयोग करता है, जिसमें इस व्यवहार का गहराई से विश्लेषण शामिल है।

द डेल कमांड

इस कमांड के कई संबंधित अलग-अलग रूप हैं।

del v

यदि v एक वेरिएबल है, तो कमांड del v वेरिएबल को उसके दायरे से हटा देता है। उदाहरण के लिए:

x = 5
print(x) # out: 5
del x
print(x) # NameError: name 'f' is not defined

ध्यान दें कि del एक बाध्यकारी घटना है , जिसका अर्थ है कि जब तक कि स्पष्ट रूप से अन्यथा ( nonlocal - global या global का उपयोग करके) नहीं कहा गया है, del v वर्तमान दायरे में v स्थानीय बना देगा। यदि आप बाहरी दायरे में v को हटाना चाहते हैं, तो del v स्टेटमेंट के समान स्कोप में nonlocal v या global v उपयोग करें।

निम्नलिखित सभी में, एक कमांड का इरादा एक डिफ़ॉल्ट व्यवहार है लेकिन भाषा द्वारा लागू नहीं किया जाता है। एक वर्ग इस तरह से लिखा जा सकता है जो इस इरादे को अमान्य करता है।

del v.name

यह कमांड v.__delattr__(name) लिए एक कॉल चलाता है।

इरादा विशेषता name अनुपलब्ध बनाना है। उदाहरण के लिए:

class A:
    pass

a = A()
a.x = 7
print(a.x) # out: 7
del a.x
print(a.x) # error: AttributeError: 'A' object has no attribute 'x'

del v[item]

यह कमांड v.__delitem__(item) लिए एक कॉल ट्रिगर करता है।

इरादा है कि item मानचित्रण वस्तु द्वारा कार्यान्वित में संबंधित नहीं होगा v । उदाहरण के लिए:

x = {'a': 1, 'b': 2}
del x['a']
print(x) #  out: {'b': 2}
print(x['a']) # error: KeyError: 'a'

del v[a:b]

यह वास्तव में v.__delslice__(a, b) कहता है।

इरादा ऊपर वर्णित एक के समान है, लेकिन स्लाइस के साथ - एकल आइटम के बजाय आइटम की श्रेणियाँ। उदाहरण के लिए:

x = [0, 1, 2, 3, 4]
del x[1:3]
print(x) #  out: [0, 3, 4]

कचरा संग्रह # डेल कमांड भी देखें।

लोकल बनाम ग्लोबल स्कोप

स्थानीय और वैश्विक क्षेत्र क्या हैं?

सभी पायथन वेरिएब जो किसी बिंदु पर कोड में सुलभ हैं, वे स्थानीय दायरे में या वैश्विक दायरे में हैं

व्याख्या यह है कि स्थानीय दायरे में वर्तमान फ़ंक्शन में परिभाषित सभी चर शामिल हैं और वैश्विक दायरे में वर्तमान फ़ंक्शन के बाहर परिवर्तनीय शामिल हैं।

foo = 1  # global

def func():
    bar = 2  # local
    print(foo)  # prints variable foo from global scope
    print(bar)  # prints variable bar from local scope

एक निरीक्षण कर सकते हैं कि कौन से चर किस दायरे में हैं। बिल्ट-इन फ़ंक्शंस locals() और globals() पूरे स्कोप को शब्दकोशों के रूप में वापस करते हैं।

foo = 1

def func():
    bar = 2
    print(globals().keys())  # prints all variable names in global scope
    print(locals().keys())  # prints all variable names in local scope

नाम बंद के साथ क्या होता है?

foo = 1

def func():
    foo = 2  # creates a new variable foo in local scope, global foo is not affected

    print(foo)  # prints 2

    # global variable foo still exists, unchanged:
    print(globals()['foo'])  # prints 1
    print(locals()['foo'])  # prints 2

वैश्विक चर को संशोधित करने के लिए, कीवर्ड global उपयोग करें:

foo = 1

def func():
    global foo
    foo = 2  # this modifies the global foo, rather than creating a local variable

फंक्शन की पूरी बॉडी के लिए स्कोप को परिभाषित किया गया है!

इसका क्या मतलब है कि एक चर समारोह के आधे के लिए वैश्विक नहीं होगा और स्थानीय बाद में, या इसके विपरीत।

foo = 1

def func():
    # This function has a local variable foo, because it is defined down below.
    # So, foo is local from this point. Global foo is hidden.

    print(foo) # raises UnboundLocalError, because local foo is not yet initialized
    foo = 7
    print(foo)

इसी तरह, ऑपोजिट:

foo = 1

def func():
    # In this function, foo is a global variable from the begining

    foo = 7  # global foo is modified

    print(foo)  # 7
    print(globals()['foo'])  # 7

    global foo  # this could be anywhere within the function
    print(foo)  # 7

कार्यों के भीतर कार्य

कार्यों के भीतर कई स्तर के कार्य हो सकते हैं, लेकिन किसी भी फ़ंक्शन के भीतर उस फ़ंक्शन और वैश्विक दायरे के लिए केवल एक स्थानीय गुंजाइश होती है। कोई मध्यवर्ती स्कोप नहीं हैं।

foo = 1

def f1():
    bar = 1

    def f2():
        baz = 2
        # here, foo is a global variable, baz is a local variable
        # bar is not in either scope
        print(locals().keys())  # ['baz']
        print('bar' in locals())  # False
        print('bar' in globals())  # False

    def f3():
        baz = 3
        print(bar)  # bar from f1 is referenced so it enters local scope of f3 (closure)
        print(locals().keys())  # ['bar', 'baz']
        print('bar' in locals())  # True
        print('bar' in globals())  # False

    def f4():
        bar = 4  # a new local bar which hides bar from local scope of f1
        baz = 4
        print(bar)
        print(locals().keys())  # ['bar', 'baz']
        print('bar' in locals())  # True
        print('bar' in globals())  # False

global बनाम nonlocal (केवल पायथन 3)

इन दोनों कीवर्ड का उपयोग उन चर तक पहुंच प्राप्त करने के लिए किया जाता है जो वर्तमान कार्यों के लिए स्थानीय नहीं हैं।

global कीवर्ड घोषित करता है कि एक नाम को एक वैश्विक चर के रूप में माना जाना चाहिए।

foo = 0  # global foo

def f1():
    foo = 1  # a new foo local in f1
    
    def f2():
        foo = 2  # a new foo local in f2
        
        def f3():
            foo = 3  # a new foo local in f3
            print(foo)  # 3
            foo = 30  # modifies local foo in f3 only
        
        def f4():
            global foo
            print(foo)  # 0
            foo = 100  # modifies global foo

दूसरी ओर, nonlocal (देखें nonlocal चर उपलब्ध अजगर 3 में), वर्तमान समारोह के स्थानीय गुंजाइश में एक संलग्न दायरे से एक स्थानीय चर लेता है।

nonlocal पर पायथन प्रलेखन से :

नॉनक्लॉक स्टेटमेंट में सूचीबद्ध पहचानकर्ताओं को ग्लोबल्स को छोड़कर निकटतम एन्कोडिंग दायरे में पहले से तय चर को संदर्भित करने का कारण बनता है।

अजगर 3.x 3.0
def f1():
    
    def f2():
        foo = 2  # a new foo local in f2

        def f3():
            nonlocal foo  # foo from f2, which is the nearest enclosing scope
            print(foo)  # 2
            foo = 20  # modifies foo from f2!


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow