সম্প্রতি আমি পাইথনের সাথে চারপাশে খেলতে শুরু করেছি এবং বন্ধ হওয়ার কাজ করার পথে আমি অদ্ভুত কিছু ঘিরে এসেছি। নিম্নলিখিত কোড বিবেচনা করুন:
adders=[0,1,2,3]
for i in [0,1,2,3]:
adders[i]=lambda a: i+a
print adders[1](3)
এটি ফাংশনগুলির একটি সহজ অ্যারে তৈরি করে যা একটি একক ইনপুট নেয় এবং কোনও সংখ্যার দ্বারা যুক্ত হওয়া ইনপুটটি ফিরিয়ে দেয়। ফাংশনগুলি for
লুপে তৈরি করা হয় যেখানে পুনরুক্তিটি i
থেকে চালানো 0
হয় 3
। এই প্রতিটি সংখ্যার জন্য একটি lambda
ফাংশন তৈরি করা হয় যা i
এটি ফাংশনের ইনপুটটিতে ক্যাপচার করে যোগ করে। শেষ লাইনটি প্যারামিটার হিসাবে দ্বিতীয় lambda
ফাংশনটিকে কল করে 3
। আমার আশ্চর্যজনক আউটপুট ছিল 6
।
আমি প্রত্যাশিত একটি 4
। আমার যুক্তিটি ছিল: পাইথনে সবকিছুই একটি বস্তু এবং সুতরাং প্রতিটি পরিবর্তনশীল এটির জন্য একটি পয়েন্টার প্রয়োজনীয় essential এর lambda
জন্য ক্লোজারগুলি তৈরি করার সময় i
, আমি এটি দ্বারা প্রত্যাশিত পূর্ণসংখ্যার অবজেক্টে একটি পয়েন্টার সঞ্চয় করার আশা করেছি i
। এর অর্থ হ'ল i
কোনও নতুন পূর্ণসংখ্যার অবজেক্টটি নির্ধারিত হওয়ার পরে এটি পূর্ববর্তী নির্মিত বন্ধের প্রভাব ফেলবে না। দুঃখের বিষয়, adders
একটি ডিবাগারের মধ্যে অ্যারের পরিদর্শন করা দেখায় যে এটি করে। সকল lambda
ফাংশন সর্বশেষ মান পড়ুন i
, 3
মধ্যে যার পরিণতিতে adders[1](3)
ফেরার 6
।
যা আমাকে নিম্নলিখিত সম্পর্কে অবাক করে তোলে:
- ক্লোজারগুলি ঠিক কী ধরবে?
lambda
বর্তমান মানটিi
এমনভাবে ধরতে ফাংশনগুলিকে বোঝানোর সর্বাধিক মার্জিত উপায় কী যাi
এর মান পরিবর্তন করলে প্রভাবিত হবে না ?
i
নাম স্থান ছেড়ে যাবে?
print i
লুপ পরে কাজ করবে না। তবে আমি এটি নিজের জন্য পরীক্ষা করেছিলাম এবং এখন দেখছি আপনি কী বোঝাতে চেয়েছিলেন - এটি কার্যকর হয়। আমার কোনও ধারণা ছিল না যে পাইপ ভেরিয়েবল অজগরে লুপের বডি পরে ge
if
, with
, try
ইত্যাদি