কম্পিউটার টিউটোরিয়াল

পাইথন TypeError: 'NoneType' object is not iterable সমাধান

পাইথনে, আপনি শুধু একটি অবজেক্টের ওপর ইটারেট করতে পারেন যদি সেই অবজেক্টের একটি ভ্যালু থাকে। এর কারণ হল ইটারেবল অবজেক্টগুলোর একটি নেক্সট আইটেম থাকে যা অ্যাক্সেস করা যায় যদি তাদের ভ্যালু None-এর সমান না হয়। আপনি যদি একটি None অবজেক্টের ওপর ইটারেট করার চেষ্টা করেন, আপনি TypeError: 'NoneType' object is not iterable এররটি এনকাউন্টার করবেন।

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

TypeError: 'NoneType' object is not iterable

একটি অবজেক্ট ইটারেবল হতে হলে, সেটিতে একটি ভ্যালু থাকতে হবে। একটি None ভ্যালু ইটারেবল নয় কারণ সেটি কোনো অবজেক্ট ধারণ করে না। None একটি নাল ভ্যালু রিপ্রেজেন্ট করে।

একটি None অবজেক্ট এবং একটি খালি ইটারেবলের মধ্যে পার্থক্য আছে। আপনার কাছে একটি খালি লিস্ট বা স্ট্রিং থাকলে এই এরর উঠে না।

এটি কারণ লিস্ট এবং স্ট্রিংর একটি ইটারেবল ডেটা টাইপ থাকে। যখন পাইথন ইন্টারপ্রেটার একটি খালি লিস্ট এনকাউন্টার করে, সেটি এর ওপর ইটারেট করে না কারণ কোনো ভ্যালু নেই। পাইথন একটি None ভ্যালুর ওপর ইটারেট করতে পারে না তাই ইন্টারপ্রেটার একটি এরর রিটার্ন করে।

এই এররটি সাধারণত হয় যখন আপনি একটি ফাংশন ডিক্লেয়ার করেন এবং একটি ভ্যালু রিটার্ন করা ভুলে যান।

একটি উদাহরণ সিনেরিও

চলুন একটি প্রোগ্রাম লিখি যা ছাত্রদের নামের একটি লিস্ট নেয় এবং সেগুলো ফিল্টার করে যাদের "E" দিয়ে শুরু হয়। আমরা সেগুলো কনসোলে প্রিন্ট করব।

শুরু করি ছাত্রদের নাম ফিল্টার করার একটি ফাংশন ডিফাইন করে:

def filter_students(class_names):
    new_class_names = []
    for c in class_names:
        if c.startswith("E"):
            new_class_names.append(c)

এই ফাংশনটি একটি for লুপ ব্যবহার করে "class_names" লিস্টের প্রতিটি আইটেমের মাধ্যমে লুপ করে। প্রতিটি আইটেমের জন্য, আমাদের লুপ চেক করে আইটেমটি "E" অক্ষরে শুরু হয় কিনা। যদি হয়, সেই নামটি "new_class_names" লিস্টে অ্যাড হয়।

পরবর্তীতে, একটি ফাংশন লিখি যা আমাদের নতুন লিস্টের মাধ্যমে যায় এবং প্রতিটি ভ্যালু কনসোলে প্রিন্ট করে:

def show_students(class_names):
    for c in class_names:
        print(c)

এখানে, আমরা ছাত্রদের একটি লিস্ট ডিক্লেয়ার করি যেটির মাধ্যমে আমাদের প্রোগ্রাম সার্চ করবে। আমরা এই ছাত্রদের লিস্টকে আমাদের filter_students ফাংশনের মাধ্যমে পাস করি:

students = ["Elena", "Peter", "Chad", "Sam"]
students_e_name = filter_students(students)

এই কোডটি filter_students ফাংশন এক্সিকিউট করে যা "E" দিয়ে শুরু হওয়া সব ছাত্র খুঁজে বের করে। যেসব ছাত্রের নাম "E" দিয়ে শুরু হয় তাদের লিস্টকে students_e_name বলা হয়। পরবর্তীতে, আমরা আমাদের show_students ফাংশন কল করি নতুন ছাত্রদের লিস্ট দেখানোর জন্য:

show_students(students_e_name)

চলুন আমাদের কোড রান করি এবং দেখি কী হয়:

Traceback (most recent call last):
File "main.py", line 14, in 
show_students(students_e_name)
File "main.py", line 8, in show_students
for c in class_names:
TypeError: 'NoneType' object is not iterable

আমাদের কোড একটি এরর মেসেজ রিটার্ন করে।

সমাধান

যখন আমরা show_students ফাংশনে class_names ভেরিয়েবলের ওপর ইটারেট করার চেষ্টা করি, আমাদের কোড একটি None ভ্যালু ডিটেক্ট করে এবং একটি এরর উঠায়। এর কারণ হল আমরা "class_names" হিসেবে পাস করা ভ্যালু None।

এই এররটি হয়েছে কারণ আমাদের filter_students ফাংশন একটি ভ্যালু রিটার্ন করে না। যখন আমরা filter_students ফাংশনের রেজাল্টকে students_e_name ভেরিয়েবলে অ্যাসাইন করি, None ভ্যালু সেট হয়।

এই এররটি সমাধান করতে, আমাদের filter_students ফাংশনে একটি ভ্যালু রিটার্ন করতে হবে:

def filter_students(class_names):
    new_class_names = []
    for c in class_names:
        if c.startswith("E"):
            new_class_names.append(c)
    # আমরা এখানে একটি রিটার্ন স্টেটমেন্ট অ্যাড করেছি
    return new_class_names
def show_students(class_names):
    for c in class_names:
        print(c)
students = ["Elena", "Peter", "Chad", "Sam"]
students_e_name = filter_students(students)
show_students(students_e_name)

এই কোডটি new_class_names এর ভ্যালু মেইন প্রোগ্রামে ফিরিয়ে দেয়।

চলুন আমাদের কোড রান করি দেখতে কাজ করছে কিনা:

Elena

আমাদের কোড এখন সফলভাবে "E" দিয়ে শুরু হওয়া ছাত্রদের নাম প্রিন্ট আউট করল।

NoneType এক্সেপশন এড়ানো

টেকনিক্যালি, আপনি NoneType এক্সেপশন এড়াতে পারেন একটি ভ্যালু None-এর সমান কিনা চেক করে তার আগে যে ভ্যালুটির ওপর ইটারেট করার চেষ্টা করছেন। নিচের কোডটি বিবেচনা করুন:

def filter_students(class_names):
    new_class_names = []
    for c in class_names:
        if c.startswith("E"):
            new_class_names.append(c)
    return new_class_names
def show_students(class_names):
    if class_names is not None:
        for c in class_names:
            print(c)
students = ["Elena", "Peter", "Chad", "Sam"]
students_e_name = filter_students(students)
show_students(students_e_name)

"show_students()" ফাংশন সফলভাবে এক্সিকিউট হয় কারণ আমরা ক্লাস_নেমস None ভ্যালু কিনা চেক করি তার আগে যে সেটির ওপর ইটারেট করার চেষ্টা করি। এটি অধিকাংশ কেসে একটি বেস্ট প্র্যাক্টিস নয় কারণ একটি NoneType এররের কারণ আপনার কোডে কোথাও অন্য স্থানে একটি সমস্যা হতে পারে।

আমরা যদি "is not None" চেকটি আমাদের ফুল প্রোগ্রামে অ্যাড করি, আমরা জানব না যে আমরা অন্য একটি ফাংশনে একটি রিটার্ন স্টেটমেন্ট মিস করেছি। সেটিই কারণ যদি আপনি এই এররটি দেখেন, আপনি সেটিকে এক্সেপ্ট করার চেষ্টা করবেন an "is not None" চেক ব্যবহার করে হ্যান্ডেল করার বদলে।



উপসংহার

TypeError: 'NoneType' object is not iterable এররটি উঠে যখন আপনি এমন একটি অবজেক্টের ওপর ইটারেট করার চেষ্টা করেন যার ভ্যালু None-এর সমান।

এই এররটি সমাধান করতে, নিশ্চিত করুন যে যেকোনো ভ্যালু আপনি ইটারেট করার চেষ্টা করছেন সেগুলো একটি ইটারেবল অবজেক্ট, স্ট্রিং বা লিস্টর মতো, অ্যাসাইন করা আছে। আমাদের উদাহরণে, আমরা একটি ফাংশনে একটি "return" স্টেটমেন্ট যোগ করা ভুলে গেছি। এতে ফাংশনটি একটি লিস্টের বদলে None রিটার্ন করল।

এখন আপনি আপনার নিজস্ব কোডে এই সাধারণ পাইথন এররটি সমাধান করার জন্য রেডি।

  1. জাভাস্ক্রিপ্ট TypeError: 'undefined' is not an object

  2. পাইথনে ইটেরেবল (Iterable) এবং ইটেরেটর (Iterator) এর পার্থক্য

  3. পাইথনে 'not in' অপারেটর কী কাজ করে?

  4. পাইথনে একসাথে একাধিক ভেরিয়েবলে মান অ্যাসাইন করার পদ্ধতি