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

পাইথন NameError: name 'self' is not defined সমাধান

"self" মানটি শুধু একটি মেথডের ভিতরে উপলব্ধ থাকে যখন একটি ফাংশন কল করা হয় এবং স্পেসিফাই করা হয়।

আপনি একটি মেথডে স্পেসিফাই করা আর্গুমেন্টগুলিতে "self" অ্যাক্সেস করতে পারবেন না, বা "self" আর্গুমেন্ট হিসেবে স্পেসিফাই না করেই একটি ফাংশনের ভিতরে। অন্যথায়, আপনি এররটি দেখবেন "NameError: name 'self' is not defined"।

এই গাইডে, আমরা এই এরর কী বোঝায় এবং কেন এটি উঠে সেটি আলোচনা করব। আমরা কিছু কোড স্নিপেটের মাধ্যমে যাব যাতে আপনি আপনার কোডে এই এররটি কীভাবে সমাধান করবেন সেটি বুঝতে পারেন।

NameError: name 'self' is not defined

"self" ভেরিয়েবলটি একটি ক্লাসের ভিতরে একটি অবজেক্ট সম্পর্কে ইনফরমেশন ধারণ করে। একটি অবজেক্টে অ্যাসাইন করা সকল ভ্যালু "self" ভেরিয়েবলে উপলব্ধ থাকে।

"self" অবশ্যই একটি আর্গুমেন্ট হিসেবে পাস করা উচিত যদি আপনি এটি একটি মেথডে ব্যবহার করতে চান। "self" ভেরিয়েবলটি একটি মেথডের অন্যান্য আর্গুমেন্টে ব্যবহার করা যাবে না কারণ এটি শুধু একটি মেথডের ভিতর থেকে অ্যাক্সেসযোগ্য।

আপনি "NameError: name 'self' is not defined" এররটি এনকাউন্টার করবেন যদি:

  • আপনি "self" কে একটি আর্গুমেন্ট হিসেবে স্পেসিফাই না করেন
  • আপনি "self" কে অন্য একটি আর্গুমেন্টে একটি আর্গুমেন্ট হিসেবে ব্যবহার করেন

চলুন এই সিনেরিওগুলো একে একে ওয়াকথ্রু করি।

সিনেরিও #১: "self" আর্গুমেন্ট হিসেবে লিস্টেড নয়

"self" অবশ্যই একটি আর্গুমেন্ট হিসেবে লিস্টেড থাকতে হবে যাতে এটি একটি মেথডে অ্যাক্সেসযোগ্য হয়। "self" একটি গ্লোবাল ভেরিয়েবল নয়। এটি একটি ক্লাসের ভিতরে লোকাল।

একটি প্রোগ্রাম লিখি যা একটি ক্লাসে মুভি সম্পর্কে ইনফরমেশন ধারণ করে। আমরা আমাদের ক্লাসকে একটি কন্সট্রাক্টর সহ ডিফাইন করে শুরু করি যেটি আমাদের মুভি সম্পর্কে ভ্যালু ধারণ করে:

class Movie:
    def __init__(self, name, year_released):
        self.name = name
        self.year_released = year_released

আমাদের ক্লাস দুটি ভ্যালু ধারণ করতে পারে: একটি মুভির নাম এবং সেটি যে বছরে রিলিজ হয়েছিল। পরবর্তীতে, আমরা একটি মেথড ডিক্লেয়ার করি যা আমাদের "year_released" এর ভ্যালু চেঞ্জ করতে দেয়:

 def change_year(year_released):
    self.year_released = year_released
    print("{} was released in {}.".format(self.name, self.year_released))

আমাদের কোড টেস্ট করতে, আমরা আমাদের ক্লাসের একটি অবজেক্ট তৈরি করি। এই অবজেক্টটি হ্যাপি গিলমোর মুভি রিপ্রেজেন্ট করে, যেটি ১৯৯৬ সালে রিলিজ হয়েছিল:

happy_gilmore = Movie("Happy Gilmore")
happy_gilmore.change_year(1996)

আমরা আমাদের অবজেক্টে change_year() মেথড কল করেছি যাতে আমরা মুভি যে বছরে রিলিজ হয়েছিল সেটি ১৯৯৬ সেট করতে পারি। চলুন আমাদের কোড রান করি এবং দেখি কাজ করে কিনা:

Traceback (most recent call last):
File "main.py", line 11, in 
happy_gilmore.change_year()
File "main.py", line 7, in change_year
self.year_released = year_released
NameError: name 'self' is not defined

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

এই এররটি উঠেছে কারণ আমরা "self" কে আমাদের মেথডে একটি আর্গুমেন্ট হিসেবে পাস করিনি। আমরা এই এররটি ফিক্স করি "self" কে change_year() মেথডে প্রথম আর্গুমেন্ট হিসেবে যোগ করে:

def change_year(self, year_released):
    self.year_released = year_released
    print("{} was released in {}.".format(self.name, self.year_released))

আবার আমাদের কোড রান করি:

Happy Gilmore was released in 1996.

আমাদের কোড সফলভাবে রান হল!

সিনেরিও #২: "self" কে অন্য একটি আর্গুমেন্টে আর্গুমেন্ট হিসেবে ব্যবহার করা

"self" ইভ্যালুয়েট হয় যখন একটি ফাংশন কল হয়। এর মানে আপনি একটি আর্গুমেন্ট থাকতে দিতে পারবেন না যেটি একটি ফাংশন কলয়ের আর্গুমেন্টের লিস্টে "self" কে রেফার করে।

আমাদের "year_released" মেথড আপডেট করি যাতে, যদি একটি ভিন্ন রিলিজ ইয়ার স্পেসিফাই করা না থাকে, একটি মেসেজ কনসোলে প্রিন্ট হয় যেটি বলে যে মুভির বছর চেঞ্জ হয়নি।

আমরা এটি আমাদের কোডে একটি ডিফল্ট আর্গুমেন্ট সেট করে করতে পারি:

def change_year(self, year_released=self.year_released):
    if year_released != self.year_released:
        self.year_released = year_released
        print("{} was released in {}.".format(self.name, self.year_released))
    else:
        print("This movie has not been changed.")
        print(year_released)

"year_released" এখন "self.year_released" এর ডিফল্ট ভ্যালু পায়। এর মানে যদি আমরা কোনো ভ্যালু স্পেসিফাই না করি যে ইয়ারটি কীতে চেঞ্জ করা উচিত, একটি ডিফল্ট ভ্যালু সেট হয়। যদি আমরা একটি ভ্যালু স্পেসিফাই করি, আমরা যে ভ্যালুটি স্পেসিফাই করেছি সেটি ডিফল্টের বদলে ব্যবহার হয়।

যদি আমরা স্পেসিফাই করা ভ্যালু "self.year_released" এর ভ্যালুর সমান না হয়, "self.year_released" এর ভ্যালু চেঞ্জ হয়। অন্যথায়, ইউজারকে বলে দেয়া হয় যে মুভিটি চেঞ্জ হয়নি একটি মেসেজ কনসোলে প্রিন্ট হয়।

আমাদের if স্টেটমেন্ট ইভ্যালুয়েট হওয়ার পর, "year_released" এর ভ্যালু কনসোলে প্রিন্ট হয়।

চলুন আমাদের কোড রান করি:

Traceback (most recent call last):
File "main.py", line 1, in 
class Movie:
File "main.py", line 6, in Movie
def change_year(self, year_released=self.year_released):
NameError: name 'self' is not defined

আমাদের কোড একটি এরর উঠায়। এর কারণ হল আমরা আমাদের আর্গুমেন্টের লিস্টে অন্য একটি আর্গুমেন্টে "self" ব্যবহার করার চেষ্টা করেছি।

আমরা এই এররটি ফিক্স করতে পারি "year_released" ভেরিয়েবলের ভ্যালু "self.year_released" সেট করে আমাদের ফাংশনের ভিতরে আমাদের আর্গুমেন্টের লিস্টে না করে:

def change_year(self, year_released=None):
    if year_released != self.year_released:
        self.year_released = year_released
        print("{} was released in {}.".format(self.name, self.year_released))
    else:
        year_released = self.year_released
        print("This movie has not been changed.")
        print(year_released)

এই কোডে, আমরা "year_released" কে "self.year_released" এর সমান সেট করি যদি আমরা আমাদের ফাংশন কলে "year_released" এর জন্য কোনো ভ্যালু স্পেসিফাই না করি।

চলুন আমাদের কোড টেস্ট আউট করার জন্য একটি নতুন Movie অবজেক্ট তৈরি করি:

happy_gilmore = Movie("Happy Gilmore", 1995)
happy_gilmore.change_year(1996)

আমরা ভুলে হ্যাপি গিলমোর যে বছরে রিলিজ হয়েছিল সেটি ১৯৯৫ হিসেবে স্পেসিফাই করেছি। আমাদের change_year() মেথড ব্যবহার করে এটিকে চেঞ্জ করতে হবে। আমাদের কোড রিটার্ন করে:

Happy Gilmore was released in 1996.
1996

আমাদের কোড সফলভাবে এক্সিকিউট হল। চলুন আমাদের কোড টেস্ট করি দেখতে কী হয় যদি "year_released" এর ভ্যালু ইতিমধ্যে সেটি সমান যা আমরা change_year() মেথডে স্পেসিফাই করি:

happy_gilmore = Movie("Happy Gilmore", 1996)
happy_gilmore.change_year(1996)

আমাদের কোড রিটার্ন করে:

This movie has not been changed.
1996

আমাদের কোড আমাদের কোডের else স্টেটমেন্ট এক্সিকিউট করল এবং আমাদের বলে দিল যে মুভিটি চেঞ্জ হয়নি।

উপসংহার

"NameError: name 'self' is not defined" এররটি উঠে যখন আপনি "self" কে একটি পজিশনাল আর্গুমেন্ট হিসেবে স্পেসিফাই করা ভুলে যান অথবা যখন আপনি একটি আর্গুমেন্টের লিস্টে অন্য একটি আর্গুমেন্টে "self" ব্যবহার করেন।

আপনি এই এররটি সমাধান করেন নিশ্চিত করে যে একটি ফাংশনে যেসব মেথড "self" ব্যবহার করে সেগুলো তাদের আর্গুমেন্টের লিস্টে "self" ইনক্লুড করে। যদি সেটি কাজ না করে, নিশ্চিত করুন যে একটি আর্গুমেন্টের লিস্টে কোনো আর্গুমেন্ট "self" এর ওপর তাদের ডিফল্ট ভ্যালুর জন্য ডিপেন্ড করে না।

এখন আপনি এই পাইথন এররটি প্রফেশনাল ডেভেলপারের মতো সমাধান করার জন্য রেডি!

  1. পাইথনে প্রাইম নম্বর চেক করা (Prime or Not)

  2. পাইথনে মিন স্ট্যাক ইমপ্লিমেন্টেশন

  3. পাইথনে ইনহেরিটেন্স (Inheritance)

  4. পাইথনে NameError এক্সসেপশন ক্যাচ করা