পাইথন ননলোকাল স্টেটমেন্ট


341

পাইথন nonlocalস্টেটমেন্টটি কী করে (পাইথন ৩.০ এবং তারপরে)?

অফিসিয়াল পাইথন ওয়েবসাইটে কোনও ডকুমেন্টেশন help("nonlocal")নেই এবং এটিও কাজ করে না।


4
এই প্রশ্নটি একবার দেখুন: stackoverflow.com/questions/1414304/local-funifications-in-python
ম্যাট

18
ননলোকালের জন্য পাইথনের অফিসিয়াল ডকুমেন্টেশনটি এখানে রয়েছে: ডকস.পিথন.আর.৩ / ৩ / রেফারেন্স / ((পাইথন ৩.০ থেকে এই ডকুমেন্টেশনটি পাওয়া যায়, সুতরাং কোনও অফিসিয়াল ডকুমেন্টেশন নেই বলে
ওপির বক্তব্যটি

3
"There is no documentation for nonlocal".আসলে, আপনি help(keyword_in_string)পাইথন 3 এবং উপরের নথির জন্য করতে পারেন
ytpillai

10
বিষয়টিতে অফিসিয়াল ডক্স ধরণের স্তন্যপায়ী হতে। নির্বাচিত উত্তরের উদাহরণ বিষয়গুলি খুব স্পষ্ট করে তোলে, এটি একটি মূল্যবান প্রশ্ন।
ম্যাড পদার্থবিজ্ঞানী

অফিসিয়াল পাইথন টিউটোরিয়ালে স্কোপস এবং নেমস্পেসগুলির একটি দুর্দান্ত উদাহরণ সহ ধারণাটির ভাল ব্যাখ্যা রয়েছে
জামন

উত্তর:


473

ব্যবহার না করে এটির তুলনা করুন nonlocal:

x = 0
def outer():
    x = 1
    def inner():
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 0

এই করতে, ব্যবহার nonlocal, যেখানে inner()'s xএখন হয় outer()এর x:

x = 0
def outer():
    x = 1
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 2
# global: 0

যদি আমরা ব্যবহার করতে globalপারি তবে xএটি সঠিকভাবে "গ্লোবাল" মানের সাথে আবদ্ধ হবে :

x = 0
def outer():
    x = 1
    def inner():
        global x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# inner: 2
# outer: 1
# global: 2

32
এটি কীভাবে গ্লোবাল এক্সের চেয়ে আলাদা?
আবলু

52
এটির অনুরূপ - তবে মনে রাখবেন যে বাইরের এক্স উদাহরণে বৈশ্বিক নয় তবে পরিবর্তে বাইরের ফাংশনে সংজ্ঞায়িত।
আনন

3
@ ডাস্টিন - আসলে, আপনি যদি একটি এট্রিবিউট এক্স এবং একটি সাবক্লাস বি এর সাথে সংজ্ঞায়িত ক্লাস এ থাকতেন তবে আপনি এক্স এর সাথে বি এর মধ্যে থেকে এক্সকে উল্লেখ করবেন
আনন

2
অভ্যন্তরীণ ফাংশনগুলি সংজ্ঞায়িত করার সময় কোডটি খুব সহজেই ভারাক্রান্ত হয়ে যায় এবং 79 টি পিআরপি 8 সুপারিশ লঙ্ঘন করে। এই সমস্যাটি পেতে কোনও উপায়? বাইরের ফাংশনটির বাইরে কোনও অভ্যন্তরীণ ফাংশন রাখা যেতে পারে? আমি জানি প্রশ্নটি বোকা লাগছে, তবে আমি আন্তরিক।
tommy.carstensen

3
@ tommy.carstensen আপনি একটি আর্গ হিসাবে ফাংশনটি পাস করতে পারেন যা উচ্চতর ক্রমের ফাংশনগুলির সৌন্দর্য। ফাংশনাল প্রোগ্রামিংয়ে একে সংমিশ্রণ বলা হয়, পাইথন একটি খাঁটি এফপি ভাষা নয় তবে আপনি অবশ্যই একটি বৈশিষ্ট্য নিয়ে খেলতে পারেন (জেনারেটর, উচ্চতর ক্রমের কয়েকটি উদাহরণ)
সুপারউসারোই

90

সংক্ষেপে, এটি আপনাকে একটি বহিরাগত (তবে অ-বৈশ্বিক) স্কোপে ভেরিয়েবলের মান নির্ধারণ করতে দেয়। সমস্ত বেহাল বিবরণের জন্য পিইপি 3104 দেখুন ।


41

"পাইথন ননলোকাল" এর জন্য একটি গুগল অনুসন্ধান প্রস্তাব, পিইপি 3104 তৈরি করেছে , যা বিবৃতিটির পিছনে সিনট্যাক্স এবং যুক্তির পুরোপুরি বর্ণনা করে। সংক্ষেপে, এটি globalস্টেটমেন্টের মতো ঠিক একইভাবে কাজ করে, এটি ছাড়াও এটি ভেরিয়েবলগুলি উল্লেখ করতে ব্যবহৃত হয় যা ফাংশনটিতে বৈশ্বিক বা স্থানীয় নয়।

আপনি এটি দিয়ে কী করতে পারেন তার একটি সংক্ষিপ্ত উদাহরণ এখানে। কাউন্টার জেনারেটরটি এটি ব্যবহার করার জন্য আবারও লেখা যেতে পারে যাতে এটি বন্ধ হয়ে যাওয়া ভাষার মূর্তিগুলির মতো আরও দেখা যায়।

def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter

স্পষ্টতই, আপনি এটি একটি জেনারেটর হিসাবে লিখতে পারেন, যেমন:

def counter_generator():
    count = 0
    while True:
        count += 1
        yield count

তবে এটি নিখুঁতভাবে অদ্ভুত অজগর, মনে হচ্ছে প্রথম সংস্করণ শুরুর দিকে কিছুটা স্পষ্ট হবে। জেনারেটর সঠিকভাবে ব্যবহার করা, ফিরে ফাংশন কল করে বিভ্রান্তির একটি সাধারণ বিষয়। প্রথম সংস্করণ স্পষ্টত একটি ফাংশন প্রদান করে।


1
আমি নিশ্চিত ছিলাম 'গ্লোবাল' কীওয়ার্ডটি সেটাই করে - উচ্চারণে এটি কাজ করে যতক্ষণ না এই নামটি পরিবর্তনশীল হয়। একটি শ্রেণীর ভিতরে মডিউল স্তরে কোনও ভেরিয়েবল এক্স ঘোষণা করা যেতে পারে, তারপরে এই শ্রেণীর অভ্যন্তরে কোনও ফাংশন এবং তারপরে সেই ফাংশনের অভ্যন্তরীণ ফাংশনে - এটি কীভাবে জানবে যে কোন এক্সকে উল্লেখ করা উচিত?
ooboo

7
গ্লোবাল সম্পর্কে জিনিস এটি শুধুমাত্র গ্লোবাল ভেরিয়েবলের জন্য কাজ করে। এটি কোনও এনকোলেজিং, নংলোবল স্কোপে ভেরিয়েবলগুলি দেখতে পাবে না।
সিঙ্গেলাইজেশন ইলিমিনেশন

আমি মেক-কাউন্টারটি চেষ্টা করেছিলাম - তবে এটি কোনও জেনারেটর না দিয়ে একটি ফাংশন দেয়। কোনও জেনারেটর ফেরত দেওয়ার কোনও উপায় আছে যাতে পরে আমি এটির উপরে পুনরুক্তি করতে পারি?
ডিজেল

@ ডিজেল: এই উদাহরণটি nonlocalপাইথনের বিবৃতিটি বর্ণনা করার উদ্দেশ্যে ; আপনি স্বাভাবিক সংখ্যার একটি ক্রম চান, পাইথন বাগ্ধারা আসলেitertools.count()
SingleNegationElimination

আমি উত্পাদনের মতো জেনারেটর ফিরিয়ে দেওয়ার ক্ষমতা ডেমো করতে চাই - ফলন আসলে একটি জেনারেটর দেয়। আমার ধারণা হ'ল ফলন ব্যবহার না করে এর পরিবর্তে ননলোকাল বা অন্য কোনও সমাধান ব্যবহার করুন
ডিজেল

15

@ooboo:

এটি উত্স কোডের রেফারেন্সের বিন্দুতে একটিকে "নিকটতম" লাগে। একে "লেক্সিকাল স্কোপিং" বলা হয় এবং এখন> 40 বছর ধরে প্রমিত।

পাইথনের ক্লাসের সদস্যরা ডাকাডোরিয়াদে সত্যই রয়েছে __dict__এবং ল্যাজিকাল স্কোপিং দিয়ে কখনই পৌঁছাতে পারে না।

আপনি যদি নির্দিষ্ট না করেও করেন nonlocalতবে x = 7এটি একটি নতুন স্থানীয় ভেরিয়েবল "x" তৈরি করবে। আপনি যদি নির্দিষ্ট nonlocalকরে থাকেন তবে এটি "নিকটতম" "x" সন্ধান করবে এবং এতে নির্ধারিত হবে। যদি আপনি নির্দিষ্ট করেন nonlocalএবং কোনও "x" না থাকে তবে এটি আপনাকে একটি ত্রুটি বার্তা দেবে।

শব্দ globalসবসময় আমার আজব লাগে করেছে যেহেতু এটি সুখে দূরতম এক জন্য ছাড়া সমস্ত উপেক্ষা করা হবে অন্যান্য "X"। রহস্যময়।


14

সহায়তা ('nonlocal') nonlocalবিবৃতি


    nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*

nonlocalবিবৃতি নিকটতম এনক্লোজিং সুযোগ পূর্বে আবদ্ধ ভেরিয়েবল উল্লেখ করতে তালিকাভুক্ত শনাক্তকারী ঘটায়। এটি গুরুত্বপূর্ণ কারণ বাইন্ডিংয়ের জন্য পূর্বনির্ধারিত আচরণ হ'ল স্থানীয় নেমস্পেসটি অনুসন্ধান করা। স্টেটমেন্টটি এনক্যাপসুলেটেড কোডটিকে গ্লোবাল (মডিউল) সুযোগ ছাড়াও স্থানীয় স্কোপের বাইরে ভেরিয়েবলগুলি রিইন্ড করতে দেয়।

nonlocalবিবৃতিতে তালিকাভুক্ত নামগুলির বিপরীতে একটি বিবৃতিতে তালিকাভুক্ত নামগুলি globalঅবশ্যই আবদ্ধ স্কোপের পূর্ব-বিদ্যমান বাইন্ডিংগুলিকে উল্লেখ করতে হবে (যে ক্ষেত্রটিতে একটি নতুন বাঁধাই তৈরি করা উচিত তা নির্বিঘ্নে নির্ধারণ করা যায় না)।

একটি nonlocalবিবৃতিতে তালিকাভুক্ত নাম অবশ্যই স্থানীয় ক্ষেত্রের পূর্ব-বিদ্যমান বাইন্ডিংগুলির সাথে সংঘর্ষে লিপ্ত হবে না।

আরো দেখুন:

পিইপি 3104 - বাহ্যিক স্কোপগুলিতে নামগুলিতে অ্যাক্সেস বিবৃতিটির
স্পেসিফিকেশন nonlocal

সম্পর্কিত সহায়তা সম্পর্কিত বিষয়: বিশ্বব্যাপী, NAMESPACES

উত্স: পাইথন ভাষার রেফারেন্স


11
প্রতিদিন নতুন কিছু শিখুন। আপনি help()কীওয়ার্ডগুলিতে ব্যবহার করতে পারবেন সে সম্পর্কে আমার কোনও ধারণা ছিল না (এবং এখন আমার মন ফুঁকছে: help()কোনও যুক্তি ছাড়াই ইন্টারেক্টিভ হয় না )।
এরিক ইয়ংরেন

6

পাইথন 3 রেফারেন্স থেকে উদ্ধৃতি :

ননলোকাল স্টেটমেন্টটি তালিকাভুক্ত শনাক্তকারীদের গ্লোবালগুলি বাদ দিয়ে নিকটস্থ এনকোলেসিং স্কোপটিতে পূর্বের আবদ্ধ ভেরিয়েবলগুলি উল্লেখ করে।

রেফারেন্সে যেমন বলা হয়েছে, বেশ কয়েকটি নেস্টেড ফাংশনের ক্ষেত্রে কেবল নিকটস্থ এনক্লোজিং ফাংশনে পরিবর্তনশীল পরিবর্তন করা হয়:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        x = 2
        innermost()
        if x == 3: print('Inner x has been modified')

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Inner x has been modified

"নিকটতম" ভেরিয়েবলটি কয়েক স্তর থেকে দূরে থাকতে পারে:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    x = 1
    inner()
    if x == 3: print('Outer x has been modified')

x = 0
outer()
if x == 3: print('Global x has been modified')

# Outer x has been modified

তবে এটি বৈশ্বিক পরিবর্তনশীল হতে পারে না:

def outer():
    def inner():
        def innermost():
            nonlocal x
            x = 3

        innermost()

    inner()

x = 0
outer()
if x == 3: print('Global x has been modified')

# SyntaxError: no binding for nonlocal 'x' found

3
a = 0    #1. global variable with respect to every function in program

def f():
    a = 0          #2. nonlocal with respect to function g
    def g():
        nonlocal a
        a=a+1
        print("The value of 'a' using nonlocal is ", a)
    def h():
        global a               #3. using global variable
        a=a+5
        print("The value of a using global is ", a)
    def i():
        a = 0              #4. variable separated from all others
        print("The value of 'a' inside a function is ", a)

    g()
    h()
    i()
print("The value of 'a' global before any function", a)
f()
print("The value of 'a' global after using function f ", a)

2

"ননলোকাল" বিবৃতি সম্পর্কে আমার ব্যক্তিগত বোঝাপড়া (এবং আমি পাইথন এবং সাধারণভাবে প্রোগ্রামিংয়ের ক্ষেত্রে নতুন হিসাবে আমাকে ক্ষমা করে দিই) "ননলোকাল" কোডটি নিজেই বডি এর পরিবর্তে পুনরাবৃত্ত ফাংশনগুলির মধ্যে গ্লোবাল কার্যকারিতা ব্যবহার করার উপায় । আপনি যদি ফাংশনগুলির মধ্যে একটি বিশ্বব্যাপী বিবৃতি।


0

'ননলোকাল' অভ্যন্তরীণ ফাংশনগুলির সাথে (যেমন; নেস্টেড অভ্যন্তরীণ ফাংশনগুলি) বাইরের প্যারেন্ট ফাংশনের নির্দিষ্ট ভেরিয়েবলের জন্য পড়ার এবং ' লেখার ' অনুমতি পেতে পারে । এবং ননলোকাল কেবলমাত্র অভ্যন্তরীণ ফাংশনগুলির মধ্যে ব্যবহার করা যেতে পারে যেমন:

a = 10
def Outer(msg):
    a = 20
    b = 30
    def Inner():
        c = 50
        d = 60
        print("MU LCL =",locals())
        nonlocal a
        a = 100
        ans = a+c
        print("Hello from Inner",ans)       
        print("value of a Inner : ",a)
    Inner()
    print("value of a Outer : ",a)

res = Outer("Hello World")
print(res)
print("value of a Global : ",a)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.