মূল content-এ যাও

Python for AI/Object-Oriented Programming/Lesson 25

Dunder Methods

__str__, __repr__, __len__, __getitem__, __eq__, __add__ — নিজের class-কে Python-এর built-in জিনিসের মতো আচরণ করানো। PyTorch-এর Dataset ঠিক এভাবেই কাজ করে।

সময়
24 মিনিট
Exercise
1
Challenge
1
Quiz
3 প্রশ্ন

সহজ ভাষায়

len("hello"), [1, 2] + [3], my_list[0], print(x) — এগুলো আসলে কীভাবে কাজ করে? Python ভেতরে ভেতরে বিশেষ নামের method ডাকে:

তুমি লেখোPython ডাকে
len(x)x.__len__()
x[i]x.__getitem__(i)
a + ba.__add__(b)
a == ba.__eq__(b)
print(x)x.__str__()
x (console-এ)x.__repr__()

নামের দুই পাশে double underscore — তাই নাম dunder (double underscore)। এগুলো নিজের class-এ লিখলে তোমার object-ও built-in জিনিসের মতো আচরণ করে।

main.py

কেন দরকার?

  • PyTorch Dataset — __len__ আর __getitem__ লিখলেই PyTorch-এর DataLoader তোমার data batch করে, shuffle করে, GPU-তে পাঠায়।
  • NumPy array — a + b দিয়ে দুটো array যোগ হয় কারণ NumPy __add__ লিখেছে।
  • Debugging — ভালো __repr__ না থাকলে print করলে দেখায় <__main__.Vector object at 0x7f...> — কিছুই বোঝা যায় না।

__str__ আর __repr__

main.py

অর্থহীন! এখন dunder যোগ করি:

main.py
  • __str__ — মানুষের জন্য, সুন্দর রূপ।
  • __repr__ — developer-এর জন্য, স্পষ্ট রূপ (আদর্শভাবে, যে code দিয়ে object-টা আবার বানানো যায়)।
  • একটাই লিখতে চাইলে __repr__ লেখো — print না পেলে সেটাই ব্যবহার করে।

{self.title!r} — f-string-এ !r মানে মানটার repr() বসাও (তাই string-এর চারপাশে quote আসে)।

__len__ আর __getitem__

main.py

শুধু __getitem__ লিখেছি, কিন্তু for loop-ও কাজ করছে! Python p[0], p[1], ... ডাকতে থাকে, যতক্ষণ না IndexError আসে। Slicing-ও কাজ করছে কারণ আমরা index-টা সরাসরি list-এ পাঠিয়ে দিচ্ছি।

__eq__: মান অনুযায়ী তুলনা

main.py

Operator overloading: __add__, __mul__

main.py
OperatorDunder
+ - * /__add__ __sub__ __mul__ __truediv__
== < >__eq__ __lt__ __gt__
x in obj__contains__
obj()__call__

Exercise

Exercise

Vector class

+20 XP

2D Vector class বানাও:

  • Vector(x, y)
  • __add__ — Vector(1, 2) + Vector(3, 4) দেবে Vector(4, 6)
  • __eq__ — দুটো vector-এর x আর y সমান হলে True
  • __repr__ — return করবে "Vector(4, 6)" আকারের string
solution.py

Quiz

  1. Q1len(obj) লিখলে Python আসলে কোন method ডাকে?
  2. Q2__str__ আর __repr__-এর পার্থক্য কী?
  3. Q3__eq__ না লিখলে Vector(1, 2) == Vector(1, 2) কী দেবে?
0/3 answered

Challenge

Challenge

PyTorch-এর মতো Dataset

+50 XP

PyTorch-এ data load করতে একটা Dataset class লিখতে হয় যেটার len() আর [index] কাজ করে। নিজে বানাও:

  • TextDataset(texts, labels)
  • len(ds) — কতগুলো sample
  • ds[i] — (text, label) tuple; text ছোট হাতের অক্ষরে আর আগে-পরের space কাটা অবস্থায়
  • negative index (ds[-1]) কাজ করবে, আর for text, label in ds: loop চলবে
solution.py

বাস্তবে কোথায় ব্যবহার হয়?

Challenge-এর TextDataset প্রায় হুবহু PyTorch-এর একটা real Dataset। PyTorch-এর DataLoader শুধু দুটো জিনিস জানতে চায় — len(ds) আর ds[i] — তারপর batch বানায়। চলো একটা সহজ batcher নিজে লিখি:

main.py

আর PyTorch-এ model(x) লিখলে যে model "ডাকা" যায় — সেটা __call__ dunder-এর কাজ। nn.Module-এর __call__ ভেতরে তোমার forward() ডাকে।

(yield হলো generator — একবারে সব না বানিয়ে একটা একটা করে দেয়। পরে বিস্তারিত দেখবো।)

Interview প্রশ্ন

  • Beginner: Dunder method কী? তিনটা উদাহরণ দাও।
  • Intermediate: __str__ আর __repr__-এর পার্থক্য কী? কোনটা অবশ্যই লেখা উচিত?
  • Advanced: __eq__ override করলে __hash__-এর কী হয়, আর কেন? (Python __hash__-কে None করে দেয় — object আর set/dict key হতে পারে না, যদি না নিজে __hash__ লেখো।)

এরপর কী?

লক্ষ্য করেছো — প্রায় প্রতিটা class-এ __init__, __repr__, __eq__ প্রায় একই রকম লিখছি? Python-এ এই বিরক্তিকর কাজ নিজে থেকে করে দেওয়ার একটা উপায় আছে। পরের lesson: Dataclasses।