পাইথন নেস্টেড ফাংশনগুলিকে ক্লোজার বলা হয় না কেন?


249

আমি পাইথনে নেস্টেড ফাংশন দেখেছি এবং ব্যবহার করেছি এবং এগুলি বন্ধের সংজ্ঞাটির সাথে মেলে। তাহলে তাদের nested functionsপরিবর্তে কেন ডাকা হয় closures?

নেস্টেড ফাংশনগুলি কি বন্ধ হয়ে যায় না কারণ তারা বাহ্যিক বিশ্বের দ্বারা ব্যবহৃত হয় না?

আপডেট: আমি ক্লোজারগুলি নিয়ে পড়ছিলাম এবং পাইথনের প্রতি শ্রদ্ধার সাথে এই ধারণাটি সম্পর্কে আমাকে ভাবতে হয়েছিল। আমি নীচে একটি মন্তব্যে কারও দ্বারা উল্লিখিত নিবন্ধটি সন্ধান করেছি এবং পেয়েছি, কিন্তু আমি এই নিবন্ধটিতে ব্যাখ্যাটি পুরোপুরি বুঝতে পারি না, এজন্যই আমি এই প্রশ্নটি জিজ্ঞাসা করছি।


8
মজার বিষয় হল, কিছু গুগল আমাকে 2006 সালের ডিসেম্বর তারিখে এটি খুঁজে পেয়েছিল: effbot.org/zone/closure.htm । আমি নিশ্চিত নই S "বাহ্যিক নকলগুলি" কি এসও তে ন্যস্ত?
এইচবিডাব্লু

উত্তর:


393

একটি বন্ধন ঘটে যখন কোনও ক্রিয়াকলাপটি কার্যকরভাবে শেষ হয়ে যায় এমন একটি এনকোলেসিং স্কোপ থেকে স্থানীয় ভেরিয়েবলের অ্যাক্সেস পায়।

def make_printer(msg):
    def printer():
        print msg
    return printer

printer = make_printer('Foo!')
printer()

যখন make_printerডাকা হয়, printerস্থায়ী হিসাবে ফাংশনটির জন্য এবং msgস্থানীয় হিসাবে এর মান হিসাবে সংকলিত কোড সহ একটি নতুন ফ্রেম স্ট্যাকের উপরে রাখা হয় । এটি তখন তৈরি করে ফাংশনটি প্রদান করে returns কারণ ফাংশনটি ভেরিয়েবলের printerউল্লেখ করে msg, make_printerফাংশনটি ফিরে আসার পরে এটি জীবিত রাখা হয় ।

সুতরাং, যদি আপনার নেস্টেড ফাংশনগুলি না করে

  1. ঘেরে দেওয়া স্কোপগুলিতে স্থানীয় যে ভেরিয়েবলগুলি অ্যাক্সেস করুন
  2. যখন তারা সেই সুযোগের বাইরে মৃত্যুদন্ড কার্যকর করা হবে,

তাহলে তারা ক্লোজার নয়।

এখানে নেস্টেড ফাংশনটির একটি উদাহরণ যা বন্ধ নয়।

def make_printer(msg):
    def printer(msg=msg):
        print msg
    return printer

printer = make_printer("Foo!")
printer()  #Output: Foo!

এখানে, আমরা একটি প্যারামিটারের ডিফল্ট মানের সাথে মানটি আবদ্ধ করছি। এটি ঘটে যখন ফাংশনটি printerতৈরি করা হয় এবং তাই msgবাহ্যিক মানের কোনও রেফারেন্সের printer পরে বজায় রাখা দরকার make_printer। এই প্রসঙ্গে msgফাংশনের একটি সাধারণ স্থানীয় পরিবর্তনশীল printer


2
আপনি উত্তর আমার চেয়ে অনেক ভাল, আপনি একটি ভাল পয়েন্ট, কিন্তু আমরা কঠোর ক্রিয়ামূলক প্রোগ্রামিং সংজ্ঞা অনুসরণ করতে যাচ্ছি, আপনার উদাহরণ এমনকি ফাংশন? এটি একটি সময় হয়েছে, এবং আমি মনে করতে পারি না যদি কঠোর ক্রিয়ামূলক প্রোগ্রামিং কোনও ফাংশনগুলিতে মান দেয় না তবে অনুমতি দেয় না return বিন্দুটি হ'ল আপনি যদি রিটার্নের মানটিকে কোনও হিসাবে বিবেচনা করেন না তবে এটি সম্পূর্ণ অন্য বিষয়।
মিকেরোবি

6
@ মিকেরোবি, আমি নিশ্চিত নই যে পাইথন আসলে কার্যকরী ভাষা নয় যদিও এটি অবশ্যই এরূপ হিসাবে ব্যবহার করা যেতে পারে সেহেতু আমাদের কার্যকরী প্রোগ্রামিং বিবেচনায় নেওয়া দরকার। তবে, না, অভ্যন্তরীণ ফাংশনগুলি সেই অর্থে ফাংশন নয় কারণ তাদের পুরো বিষয়টি পার্শ্ব প্রতিক্রিয়া তৈরি করা। একটি ফাংশন তৈরি করা সহজ যা পয়েন্টগুলি ঠিক যেমনটি চিত্রিত করে,
অ্যারোনাস্টারিং

31
@ মিকেরোবি: কোডের একটি ব্লব একটি বন্ধ হওয়া বা না হওয়া নির্ভর করে এটি তার পরিবেশের উপরে বন্ধ হয় কিনা তা আপনি নির্ভর করে না কেন তার উপর নির্ভর করে। এটি একটি রুটিন, ফাংশন, পদ্ধতি, পদ্ধতি, ব্লক, সাবরুটিন যা কিছু হোক না কেন হতে পারে। রুবিতে, পদ্ধতিগুলি ক্লোজার হতে পারে না, কেবল ব্লকগুলিই পারে। জাভাতে, পদ্ধতিগুলি ক্লোজার হতে পারে না, তবে ক্লাস করতে পারে। এটি তাদের কোনও বন্ধ করার চেয়ে কম করে না। (যদিও তারা কেবল কয়েকটি ভেরিয়েবলের উপর নির্ভর করে এবং এগুলি সংশোধন করতে পারে না, এগুলি অকেজোের পাশে করে দেয়)) আপনি তর্ক করতে পারেন যে কোনও পদ্ধতি কেবলমাত্র একটি প্রক্রিয়া বন্ধ রয়েছে self। (জাভাস্ক্রিপ্ট / পাইথনে এটি প্রায় সত্য))
জার্গ ডব্লু মিট্টাগ

3
@ JörgWMittag দয়া করে "ক্লোজস ওভার" সংজ্ঞা দিন।
এভেজেনি সার্জিভ

4
@ এভেজেনিসারজিভ "বন্ধ" অর্থাৎ "স্থানীয় ভেরিয়েবলের কাছে উল্লেখ করুন [বলুন i] একটি ঘেরের সুযোগ থেকে " refers বোঝায়, অর্থাত্ (বা পরিবর্তন) iএর মান পরিদর্শন করতে পারে, এমনকি / যখন সেই সুযোগটি "তার কার্যকারিতা শেষ করে", অর্থাৎ কোনও প্রোগ্রামের সম্পাদন কোডের অন্যান্য অংশে চলে গেছে forth ব্লক যেখানে iসংজ্ঞায়িত করা হয়েছে তা আর নেই, তবুও ফাংশন (গুলি) iএখনও উল্লেখ করতে পারে। এটি সাধারণত "ভেরিয়েবলের ওপরে ক্লোজিং" হিসাবে বর্ণনা করা হয় i। নির্দিষ্ট ভেরিয়েবলের সাথে ডিল না করার জন্য, এটি পুরো পরিবেশের ফ্রেমের উপর যেখানে ক্লেরিকটি সংজ্ঞায়িত করা হয়েছে সেখানে বন্ধ হিসাবে প্রয়োগ করা যেতে পারে।
নেস

103

অ্যারোনস্টার্লিং দ্বারা ইতিমধ্যে প্রশ্নের উত্তর দেওয়া হয়েছে

তবে, কেউ কীভাবে ভুডিয়ালগুলি হুডের নীচে সংরক্ষণ করা হয় সে সম্পর্কে আগ্রহী হতে পারে।

স্নিপেটে আসার আগে:

বন্ধগুলি এমন ফাংশন যা তাদের ঘেরের পরিবেশ থেকে পরিবর্তনশীল হয় inherit যখন আপনি কোনও ফাংশন কলব্যাককে অন্য কোনও ক্রিয়াকলাপের জন্য আর্গুমেন্ট হিসাবে পাস করবেন যা I / O করবে তখন, এই কলব্যাক ফাংশনটি পরবর্তী সময়ে শুরু করা হবে, এবং এই ফাংশনটি প্রায় জাদুকরভাবে - উপলভ্য সমস্ত ভেরিয়েবলগুলি সহ এটি প্রাসঙ্গিকভাবে মনে রাখবেন সেই প্রসঙ্গে

  • যদি কোনও ফাংশন ফ্রি ভেরিয়েবল ব্যবহার না করে তবে এটি বন্ধের রূপ দেয় না।

  • যদি অন্য কোনও অভ্যন্তরীণ স্তর থাকে যা নিখরচায় ভেরিয়েবল ব্যবহার করে - সমস্ত পূর্ববর্তী স্তরগুলি লেজিকাল পরিবেশ সংরক্ষণ করে (উদাহরণের শেষে)

  • ফাংশন বৈশিষ্ট্য func_closure মধ্যে পাইথন <3.x বা __closure__পাইথন মধ্যে> 3.x সংরক্ষণ বিনামূল্যে ভেরিয়েবল।

  • পাইথনের প্রতিটি ফাংশনটিতে এই ক্লোজার বৈশিষ্ট্য রয়েছে তবে কোনও বিনামূল্যে ভেরিয়েবল না থাকলে এটি কোনও সামগ্রী সংরক্ষণ করে না।

উদাহরণস্বরূপ: ক্লোজার অ্যাট্রিবিউটসের তবে কোনও ফ্রি ভেরিয়েবল নেই বলে ভিতরে কোনও সামগ্রী নেই।

>>> def foo():
...     def fii():
...         pass
...     return fii
...
>>> f = foo()
>>> f.func_closure
>>> 'func_closure' in dir(f)
True
>>>

নোট: নিখরচায় বৈচিত্র্য একটি ক্লোজার তৈরি করা আবশ্যক।

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

>>> def make_printer(msg):
...     def printer():
...         print msg
...     return printer
...
>>> printer = make_printer('Foo!')
>>> printer()  #Output: Foo!

এবং সমস্ত পাইথন ফাংশনগুলির একটি ক্লোজার অ্যাট্রিবিউট থাকে সুতরাং আসুন একটি ক্লোজার ফাংশনের সাথে যুক্ত এনক্লোজিং ভেরিয়েবলগুলি পরীক্ষা করা যাক।

func_closureফাংশনটির জন্য এখানে বৈশিষ্ট্য দেওয়া আছেprinter

>>> 'func_closure' in dir(printer)
True
>>> printer.func_closure
(<cell at 0x108154c90: str object at 0x108151de0>,)
>>>

দ্য closureঅ্যাট্রিবিউট সেল বস্তু যা ভেরিয়েবল এনক্লোজিং সুযোগ সংজ্ঞায়িত বিবরণ ধারণ একটি tuple ফেরৎ।

ফানক_ক্লোজারের প্রথম উপাদান যা কোনওটিই হতে পারে না এমন ফাংশনটির মুক্ত ভেরিয়েবলগুলির জন্য বাইন্ডিংগুলি ধারণ করে এমন কোষগুলির একটি টুপল এবং এটি কেবল পঠনযোগ্য।

>>> dir(printer.func_closure[0])
['__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__getattribute__',
 '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
 '__setattr__',  '__sizeof__', '__str__', '__subclasshook__', 'cell_contents']
>>>

উপরের আউটপুটটিতে আপনি দেখতে পাচ্ছেন cell_contents, আসুন এটি কী সংরক্ষণ করে তা দেখুন:

>>> printer.func_closure[0].cell_contents
'Foo!'    
>>> type(printer.func_closure[0].cell_contents)
<type 'str'>
>>>

সুতরাং, যখন আমরা ফাংশনটি ডাকি printer(), এটির মধ্যে সঞ্চিত মানটি অ্যাক্সেস করেcell_contents । এভাবেই আমরা 'ফু' হিসাবে আউটপুটটি পেয়েছি!

আবার আমি কিছু পরিবর্তন সহ উপরের স্নিপেট ব্যবহার করে ব্যাখ্যা করব:

 >>> def make_printer(msg):
 ...     def printer():
 ...         pass
 ...     return printer
 ...
 >>> printer = make_printer('Foo!')
 >>> printer.func_closure
 >>>

উপরের স্নিপেটে, আমি প্রিন্টারের ফাংশনের ভিতরে চিত্র মুদ্রণ করি না, সুতরাং এটি কোনও মুক্ত পরিবর্তনশীল তৈরি করে না। কোনও মুক্ত পরিবর্তনশীল না থাকায় বন্ধের অভ্যন্তরে কোনও সামগ্রী থাকবে না। ঠিক উপরে যা আমরা উপরে দেখি।

এখন আমি এর Free Variableসাথে সমস্ত কিছু পরিষ্কার করার জন্য আরও একটি আলাদা স্নিপেট ব্যাখ্যা করব Closure:

>>> def outer(x):
...     def intermediate(y):
...         free = 'free'
...         def inner(z):
...             return '%s %s %s %s' %  (x, y, free, z)
...         return inner
...     return intermediate
...
>>> outer('I')('am')('variable')
'I am free variable'
>>>
>>> inter = outer('I')
>>> inter.func_closure
(<cell at 0x10c989130: str object at 0x10c831b98>,)
>>> inter.func_closure[0].cell_contents
'I'
>>> inn = inter('am')

সুতরাং, আমরা দেখতে পাচ্ছি যে func_closureসম্পত্তি একটি ক্লোজার কোষগুলির একটি দ্বিখণ্ডিত, আমরা সেগুলি এবং তাদের বিষয়বস্তু স্পষ্টভাবে উল্লেখ করতে পারি - একটি ঘরে "সেল_কন্টেন্টস" এর সম্পত্তি রয়েছে

>>> inn.func_closure
(<cell at 0x10c9807c0: str object at 0x10c9b0990>, 
 <cell at 0x10c980f68: str object at   0x10c9eaf30>, 
 <cell at 0x10c989130: str object at 0x10c831b98>)
>>> for i in inn.func_closure:
...     print i.cell_contents
...
free
am 
I
>>>

এখানে যখন আমরা কল করব তখন innএটি সংরক্ষণের সমস্ত বিনামূল্যে ভেরিয়েবলগুলি উল্লেখ করবে weI am free variable

>>> inn('variable')
'I am free variable'
>>>

9
পাইথন 3 func_closureএ এখন __closure__একই সাথে বলা হয় অন্যান্য বিভিন্ন func_*বৈশিষ্ট্যের সাথে।
lvc

3
এছাড়াও __closure_পাইথন পাওয়া পাইথন 3. সাথে সামঞ্জস্যের জন্য 2.6+
পিয়ের

ক্লোজারটি সেই রেকর্ডকে বোঝায় যা ক্লোজড-ওভার ভেরিয়েবলগুলি ফাংশন অবজেক্টের সাথে সংযুক্ত করে stores এটি নিজেই ফাংশন নয়। পাইথনে, এটি হ'ল এটি __closure__বন্ধ।
মার্টিজন পিটারস

আপনার স্পষ্টতার জন্য @ মার্তিজন পিটারসকে ধন্যবাদ।
জেমস সপম

71

পাইথনের বন্ধের জন্য দুর্বল সমর্থন রয়েছে। জাভাস্ক্রিপ্ট দিয়ে ক্লোজার ব্যবহার করে কাউন্টারটির নীচের উদাহরণটি ধরুন আমি কী বলতে চাইছি তা দেখার জন্য:

function initCounter(){
    var x = 0;
    function counter  () {
        x += 1;
        console.log(x);
    };
    return counter;
}

count = initCounter();

count(); //Prints 1
count(); //Prints 2
count(); //Prints 3

বন্ধটি বেশ মার্জিত কারণ এটি "অভ্যন্তরীণ মেমরি" রাখার ক্ষমতা এই জাতীয় লিখিত ফাংশন দেয়। পাইথন ২.7 হিসাবে এটি সম্ভব নয়। যদি তুমি চেষ্টা কর

def initCounter():
    x = 0;
    def counter ():
        x += 1 ##Error, x not defined
        print x
    return counter

count = initCounter();

count(); ##Error
count();
count();

এক্স সংজ্ঞায়িত নয় বলে আপনি একটি ত্রুটি পাবেন। তবে এটি কীভাবে হতে পারে যদি এটি অন্যরা দেখায় যে আপনি এটি মুদ্রণ করতে পারেন? এটি পাইথন কীভাবে এটি ফাংশনগুলির পরিবর্তনশীল সুযোগকে পরিচালনা করে। অভ্যন্তরীণ ফাংশন বাইরের ফাংশনের ভেরিয়েবলগুলি পড়তে পারে তবে এটি সেগুলি লিখতে পারে না ।

এটা সত্যিই লজ্জাজনক। তবে কেবলমাত্র পঠনযোগ্য বন্ধের সাথে আপনি কমপক্ষে ফাংশন ডেকরেটার প্যাটার্নটি প্রয়োগ করতে পারেন যার জন্য পাইথন সিনট্যাকটিক চিনি সরবরাহ করে।

হালনাগাদ

এটি যেমন উল্লেখ করা হয়েছে, অজগরটির স্কোপ সীমাবদ্ধতাগুলি মোকাবেলা করার উপায় রয়েছে এবং আমি কিছু প্রকাশ করব।

1.global কীওয়ার্ডটি ব্যবহার করুন (সাধারণত প্রস্তাবিত নয়)।

২. পাইথন ৩.x এ, nonlocalকীওয়ার্ডটি ব্যবহার করুন (@ ইউন্টবু এবং @ লেওজেড দ্বারা প্রস্তাবিত)

৩. একটি সাধারণ পরিমার্জনযোগ্য শ্রেণীর সংজ্ঞা দাওObject

class Object(object):
    pass

এবং ভেরিয়েবলগুলি সংরক্ষণ Object scopeকরার initCounterজন্য একটি ভিতরে তৈরি করুন

def initCounter ():
    scope = Object()
    scope.x = 0
    def counter():
        scope.x += 1
        print scope.x

    return counter

যেহেতু scopeসত্যই কেবল একটি রেফারেন্স, এর ক্ষেত্রগুলির সাথে গৃহীত পদক্ষেপগুলি সত্যই scopeনিজেকে পরিবর্তন করে না, তাই কোনও ত্রুটি দেখা দেয় না।

৪. @ututbu দ্বারা নির্দেশিত হিসাবে একটি বিকল্প উপায় হ'ল প্রতিটি ভেরিয়েবলকে অ্যারে ( x = [0]) হিসাবে সংজ্ঞায়িত করা এবং এটির প্রথম উপাদানটি ( x[0] += 1) সংশোধন করা । আবার কোনও ত্রুটি দেখা দেয় না কারণ xনিজেই পরিবর্তিত হয়নি।

৫. @raxacoricofallapatorius এর পরামর্শ অনুসারে আপনি এর xসম্পত্তি তৈরি করতে পারেনcounter

def initCounter ():

    def counter():
        counter.x += 1
        print counter.x

    counter.x = 0
    return counter

27
এই চারপাশে উপায় আছে। পাইথন 2 এ, আপনি x = [0]বাইরের স্কোপটি তৈরি করতে এবং অভ্যন্তরের স্কোপটিতে ব্যবহার করতে পারেন x[0] += 1। পাইথন 3 এ, আপনি নিজের কোডটি ঠিক সেভাবেই রাখতে পারেন এবং ননলোকাল কীওয়ার্ডটি ব্যবহার করতে পারেন ।
আনটবু

"যদিও অভ্যন্তরীণ ফাংশন বাইরের ফাংশনের ভেরিয়েবলগুলি পড়তে পারে তবে এটি সেগুলি লিখতে পারে না।" - এটি আনটবুর মন্তব্য অনুসারে ভুল। সমস্যাটি হ'ল পাইথন যখন x = ... এর মতো কোনও কিছুর মুখোমুখি হয়, এক্সকে স্থানীয় ভেরিয়েবল হিসাবে ব্যাখ্যা করা হয় যা অবশ্যই এখনও সেই সময়ে সংজ্ঞায়িত হয়নি। OTOH, x যদি একটি পরিবর্তনীয় পদ্ধতিযুক্ত একটি পরিবর্তনযোগ্য অবজেক্ট হয় তবে এটি ঠিক সূক্ষ্মভাবে সংশোধন করা যেতে পারে, উদাহরণস্বরূপ x যদি এমন কোনও বস্তু যা ইনক () পদ্ধতিটিকে সমর্থন করে যা নিজেকে পরিবর্তন করে, x.inc () কোনও বাধা ছাড়াই কাজ করবে।
থানহ ডেকে

@ থানহিসডিকে এর অর্থ এই নয় যে আপনি চলকটিতে লিখতে পারবেন না? আপনি যখন কোনও পরিবর্তনীয় অবজেক্ট থেকে কলটি কোনও পদ্ধতি ব্যবহার করেন, আপনি কেবল নিজেকে পরিবর্তন করতে বলছেন, আপনি আসলে পরিবর্তনশীলটি পরিবর্তন করছেন না (যা কেবলমাত্র অবজেক্টের একটি রেফারেন্স ধারণ করে)। অন্য কথায়, পরিবর্তনশীলটি যে রেফারেন্সটিকে xনির্দেশ করে তা আপনি একইভাবে রয়েছেন এমনকি আপনি কল করেন inc()বা যাই হোক না কেন, এবং আপনি কার্যকরভাবে ভেরিয়েবলটিতে লিখেন নি।
ব্যবহারকারী 193130

4
একটি সম্পত্তি তৈরির ক্ষেত্রেxcounter # 2, imv এর চেয়ে কঠোরভাবে আরও একটি বিকল্প রয়েছে
orome

9
পাইথন 3 এর nonlocalকীওয়ার্ড রয়েছে যা globalবাইরের ফাংশনের ভেরিয়েবলের মতো তবে। এটি একটি অভ্যন্তরীণ ফাংশনটিকে এর বাইরের ফাংশন (গুলি) থেকে কোনও নাম পুনঃসামগ্রহন করার অনুমতি দেবে। আমি "নামের সাথে বাঁধাই করা" "ভেরিয়েবলটি সংশোধন করুন" এর চেয়ে আরও নির্ভুল বলে মনে করি।
লিউজ

16

পাইথন 2 এর ক্লোজার ছিল না - এর ক্লোজারগুলির সাথে সাদৃশ্যপূর্ণ ওয়ার্কআরউন্ডস ছিল।

ইতিমধ্যে দেওয়া উত্তরগুলিতে প্রচুর উদাহরণ রয়েছে - অভ্যন্তরীণ ফাংশনে ভেরিয়েবলগুলিতে অনুলিপি করা, অভ্যন্তরীণ ফাংশনে কোনও বস্তুর পরিবর্তন করা ইত্যাদি

পাইথন 3 এ, সমর্থন আরও স্পষ্ট - এবং সংশ্লেষ:

def closure():
    count = 0
    def inner():
        nonlocal count
        count += 1
        print(count)
    return inner

ব্যবহার:

start = closure()
start() # prints 1
start() # prints 2
start() # prints 3

nonlocalশব্দ এটা পরিক্ষেপ, বাইরের পরিবর্তনশীল স্পষ্টভাবে উল্লেখিত ভেতরের ফাংশন binds কার্যকরী। সুতরাং আরও স্পষ্টভাবে একটি 'বন্ধ'।


1
আকর্ষণীয়, রেফারেন্সের জন্য: docs.python.org/3/references/… । পাইথন 3 ডকুমেন্টেশনে ক্লোজারগুলি (এবং জেএস থেকে আসা আপনি কীভাবে তাদের আচরণের প্রত্যাশা করতে পারেন) এবং কীভাবে আপনি এটি আশা করতে পারেন তা কেন জানি না?
ইউজার 3773048

9

আমার একটি পরিস্থিতি ছিল যেখানে আমার পৃথক তবে অবিচ্ছিন্ন নামের জায়গার প্রয়োজন। আমি ক্লাস ব্যবহার করেছি। আমি অন্যথায় না। বিচ্ছিন্ন তবে অবিচ্ছিন্ন নামগুলি ক্লোজার।

>>> class f2:
...     def __init__(self):
...         self.a = 0
...     def __call__(self, arg):
...         self.a += arg
...         return(self.a)
...
>>> f=f2()
>>> f(2)
2
>>> f(2)
4
>>> f(4)
8
>>> f(8)
16

# **OR**
>>> f=f2() # **re-initialize**
>>> f(f(f(f(2)))) # **nested**
16

# handy in list comprehensions to accumulate values
>>> [f(i) for f in [f2()] for i in [2,2,4,8]][-1] 
16

6
def nested1(num1): 
    print "nested1 has",num1
    def nested2(num2):
        print "nested2 has",num2,"and it can reach to",num1
        return num1+num2    #num1 referenced for reading here
    return nested2

দেয়:

In [17]: my_func=nested1(8)
nested1 has 8

In [21]: my_func(5)
nested2 has 5 and it can reach to 8
Out[21]: 13

এটি বন্ধ কী কী এবং এটি কীভাবে ব্যবহার করা যায় তার একটি উদাহরণ।


0

আমি পাইথন এবং জেএস উদাহরণের মধ্যে অন্য একটি সহজ তুলনা প্রস্তাব দিতে চাই, যদি এটি বিষয়গুলিকে আরও পরিষ্কার করতে সহায়তা করে।

জাতীয়:

function make () {
  var cl = 1;
  function gett () {
    console.log(cl);
  }
  function sett (val) {
    cl = val;
  }
  return [gett, sett]
}

এবং কার্যকর:

a = make(); g = a[0]; s = a[1];
s(2); g(); // 2
s(3); g(); // 3

পাইথন:

def make (): 
  cl = 1
  def gett ():
    print(cl);
  def sett (val):
    cl = val
  return gett, sett

এবং কার্যকর:

g, s = make()
g() #1
s(2); g() #1
s(3); g() #1

কারণ: উপরে অন্য অনেকে যেমন অজগরকে বলেছিলেন, যদি একই নামের ভেরিয়েবলের অভ্যন্তরীণ সুযোগে কোনও অ্যাসাইনমেন্ট থাকে তবে অভ্যন্তরীণ সুযোগে একটি নতুন রেফারেন্স তৈরি হয়। জেএসের সাথে তেমনটা নয়, আপনি varকীওয়ার্ডের সাথে স্পষ্টভাবে কোনওটি ঘোষণা না করা পর্যন্ত ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.