🐍 آموزش جامع Python — پست ۹۹
متدهای Static در کلاس |
تا اینجا با متدهای معمولی کلاس آشنا شدیم؛ متدهایی که
اما گاهی متدی داریم که به هیچ شیء خاصی از کلاس نیاز ندارد.
در این حالت میتوانیم از
🔹 مثال ساده
میتوانیم بدون ساختن شیء از آن استفاده کنیم:
خروجی:
🔹 تفاوت با متد معمولی
متد معمولی:
برای استفاده:
اما
و میتوانیم مستقیماً بنویسیم:
🔹 آیا از طریق شیء هم میشود؟
بله:
خروجی:
اما نکته مهم این است که
🔹 مثال کاربردی
فرض کنیم کلاسی برای کار با کاربران داریم:
استفاده:
خروجی:
این متد به
⚠️ نکته مهم
بنابراین:
با این ساختار:
متفاوت است.
🧠 خلاصه
اگر یک متد:
به
به اطلاعات نمونهی کلاس وابسته نیست.
فقط یک عملیات مستقل مرتبط با کلاس انجام میدهد.
میتوانیم از:
استفاده کنیم.
مثلاً:
فراخوانی:
🎯 تمرین
کلاسی به نام
مثلاً:
خروجی:
پست ۹۹ از دوره جامع Python 🐍
متدهای Static در کلاس |
@staticmethodتا اینجا با متدهای معمولی کلاس آشنا شدیم؛ متدهایی که
self دریافت میکنند.اما گاهی متدی داریم که به هیچ شیء خاصی از کلاس نیاز ندارد.
در این حالت میتوانیم از
@staticmethod استفاده کنیم.🔹 مثال ساده
class Calculator:
@staticmethod
def add(a, b):
return a + b
میتوانیم بدون ساختن شیء از آن استفاده کنیم:
print(Calculator.add(10, 5))
خروجی:
15
🔹 تفاوت با متد معمولی
متد معمولی:
class Calculator:
def add(self, a, b):
return a + b
برای استفاده:
calc = Calculator()
print(calc.add(10, 5))
اما
staticmethod نیازی به self ندارد:class Calculator:
@staticmethod
def add(a, b):
return a + b
و میتوانیم مستقیماً بنویسیم:
Calculator.add(10, 5)
🔹 آیا از طریق شیء هم میشود؟
بله:
calc = Calculator()
print(calc.add(10, 5))
خروجی:
15
اما نکته مهم این است که
add() به اطلاعات داخل calc وابسته نیست.🔹 مثال کاربردی
فرض کنیم کلاسی برای کار با کاربران داریم:
class User:
@staticmethod
def is_valid_age(age):
return age >= 18
استفاده:
print(User.is_valid_age(20))
print(User.is_valid_age(15))
خروجی:
True
False
این متد به
self یا اطلاعات یک کاربر خاص نیاز ندارد؛ فقط یک مقدار دریافت میکند و نتیجه میدهد.⚠️ نکته مهم
@staticmethod باعث میشود Python هنگام فراخوانی متد، self را به صورت خودکار ارسال نکند.بنابراین:
@staticmethod
def add(a, b):
return a + b
با این ساختار:
def add(self, a, b):
متفاوت است.
🧠 خلاصه
اگر یک متد:
به
self نیاز ندارد.به اطلاعات نمونهی کلاس وابسته نیست.
فقط یک عملیات مستقل مرتبط با کلاس انجام میدهد.
میتوانیم از:
@staticmethod
استفاده کنیم.
مثلاً:
class Calculator:
@staticmethod
def add(a, b):
return a + b
فراخوانی:
Calculator.add(10, 5)
🎯 تمرین
کلاسی به نام
Math بساز و یک staticmethod به نام square ایجاد کن که مربع یک عدد را برگرداند.مثلاً:
print(Math.square(6))
خروجی:
36
پست ۹۹ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۰۰
متدهای Class در Python |
در پست قبل با
حالا نوع دیگری از متدها را یاد میگیریم:
این متد به جای
🔹 مثال ساده
استفاده:
خروجی:
اینجا
🔹 تغییر مقدار Class Attribute
حالا:
خروجی:
🔹 تفاوت
در متد معمولی:
اما در
🔹 یک کاربرد مهم: Alternative Constructor
یکی از کاربردهای رایج
حالا:
خروجی:
اینجا:
یک نمونهی جدید از کلاس ایجاد میکند.
⚠️ نکته مهم
سه حالت مهم را از هم جدا کن:
→ متد معمولی و مرتبط با نمونه
→ متد مرتبط با کلاس
→ متدی که به
🧠 خلاصه
نوع متد
پارامتر اصلی
وابستگی
معمولی
نمونه
کلاس
ندارد
مستقل
🎯 تمرین
کلاس زیر را کامل کن:
طوری بنویس که:
خروجی:
✅ پاسخ کامل تمرین
خروجی:
در این مثال:
رشته را به دو بخش تقسیم میکند:
سپس:
با استفاده از
پست ۱۰۰ از دوره جامع Python 🐍
متدهای Class در Python |
@classmethodدر پست قبل با
@staticmethod آشنا شدیم.حالا نوع دیگری از متدها را یاد میگیریم:
@classmethod.این متد به جای
self، یک پارامتر به نام cls دریافت میکند که به خود کلاس اشاره دارد.🔹 مثال ساده
class Person:
count = 0
@classmethod
def show_count(cls):
return cls.count
استفاده:
print(Person.show_count())
خروجی:
0
اینجا
cls به کلاس Person اشاره میکند.🔹 تغییر مقدار Class Attribute
class Person:
count = 0
@classmethod
def increase_count(cls):
cls.count += 1
حالا:
Person.increase_count()
Person.increase_count()
print(Person.count)
خروجی:
2
🔹 تفاوت
self و clsدر متد معمولی:
def method(self):
self به نمونهی کلاس اشاره میکند.اما در
classmethod:@classmethod
def method(cls):
cls به خود کلاس اشاره میکند.🔹 یک کاربرد مهم: Alternative Constructor
یکی از کاربردهای رایج
classmethod ساختن یک شیء با روش دیگری است.class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def from_string(cls, data):
name, age = data.split(",")
return cls(name, int(age))
حالا:
person = Person.from_string("Ali,25")
print(person.name)
print(person.age)خروجی:
Ali
25
اینجا:
return cls(name, int(age))
یک نمونهی جدید از کلاس ایجاد میکند.
⚠️ نکته مهم
سه حالت مهم را از هم جدا کن:
def method(self):
→ متد معمولی و مرتبط با نمونه
@classmethod
def method(cls):
→ متد مرتبط با کلاس
@staticmethod
def method():
→ متدی که به
self و cls نیاز ندارد.🧠 خلاصه
نوع متد
پارامتر اصلی
وابستگی
معمولی
selfنمونه
classmethodclsکلاس
staticmethodندارد
مستقل
🎯 تمرین
کلاس زیر را کامل کن:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
@classmethod
def from_string(cls, data):
# کد اینجا
طوری بنویس که:
product = Product.from_string("Laptop,1200")
print(product.name)
print(product.price)خروجی:
Laptop
1200
✅ پاسخ کامل تمرین
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
@classmethod
def from_string(cls, data):
name, price = data.split(",")
return cls(name, int(price))
product = Product.from_string("Laptop,1200")
print(product.name)
print(product.price)
خروجی:
Laptop
1200
در این مثال:
data.split(",")رشته را به دو بخش تقسیم میکند:
Laptop
1200
سپس:
return cls(name, int(price))
با استفاده از
cls یک شیء جدید از Product میسازد.پست ۱۰۰ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۰۱
کنترل دسترسی به ویژگیها با
در کلاسها معمولاً ویژگیها را مستقیماً از طریق شیء میخوانیم:
اما گاهی میخواهیم هنگام دسترسی به یک ویژگی، منطق خاصی اجرا شود.
برای این کار میتوانیم از
🔹 مثال ساده
حالا:
خروجی:
دقت کن که
نه مثل تابع:
🔹 چرا
بدون
و استفاده کنیم:
اما با
خواندن مقدار طبیعیتر و شبیه دسترسی به یک ویژگی معمولی است.
🔹 مثال کاربردی
استفاده:
خروجی:
هر بار که
⚠️ نکته مهم
متدی که با
نه:
🧠 خلاصه
سپس:
🎯 تمرین
کلاس زیر را کامل کن:
طوری بنویس که:
خروجی:
✅ پاسخ کامل تمرین
خروجی:
در اینجا:
قطر دایره را محاسبه میکند.
چون
و به دلیل استفاده از
پست ۱۰۱ از دوره جامع Python 🐍
کنترل دسترسی به ویژگیها با
@propertyدر کلاسها معمولاً ویژگیها را مستقیماً از طریق شیء میخوانیم:
class Person:
def __init__(self, name):
self.name = name
person = Person("Ali")
print(person.name)
اما گاهی میخواهیم هنگام دسترسی به یک ویژگی، منطق خاصی اجرا شود.
برای این کار میتوانیم از
@property استفاده کنیم.🔹 مثال ساده
class Person:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@property
def full_name(self):
return f"{self.first_name} {self.last_name}"
حالا:
person = Person("Ali", "Ahmadi")
print(person.full_name)خروجی:
Ali Ahmadi
دقت کن که
full_name را مثل ویژگی استفاده کردیم:person.full_name
نه مثل تابع:
person.full_name()
🔹 چرا
@property مفید است؟بدون
property ممکن بود مجبور شویم یک متد بنویسیم:def get_full_name(self):
return f"{self.first_name} {self.last_name}"
و استفاده کنیم:
person.get_full_name()
اما با
@property:person.full_name
خواندن مقدار طبیعیتر و شبیه دسترسی به یک ویژگی معمولی است.
🔹 مثال کاربردی
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
استفاده:
rectangle = Rectangle(10, 5)
print(rectangle.area)
خروجی:
50
هر بار که
rectangle.area را میخوانیم، مقدار مساحت محاسبه میشود.⚠️ نکته مهم
متدی که با
@property مشخص شده، هنگام استفاده بدون () فراخوانی میشود:rectangle.area
نه:
rectangle.area()
🧠 خلاصه
@property به ما اجازه میدهد یک متد را مانند یک ویژگی استفاده کنیم.@property
def area(self):
return self.width * self.height
سپس:
rectangle.area
🎯 تمرین
کلاس زیر را کامل کن:
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def diameter(self):
# کد اینجا
طوری بنویس که:
circle = Circle(5)
print(circle.diameter)
خروجی:
10
✅ پاسخ کامل تمرین
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def diameter(self):
return self.radius * 2
circle = Circle(5)
print(circle.diameter)
خروجی:
10
در اینجا:
return self.radius * 2
قطر دایره را محاسبه میکند.
چون
radius برابر 5 است:5 × 2 = 10
و به دلیل استفاده از
@property، برای دسترسی به diameter نیازی به () نداریم:circle.diameter
پست ۱۰۱ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۰۲
تغییر مقدار ویژگی با
در پست قبل یاد گرفتیم با
اما اگر بخواهیم هنگام تغییر مقدار هم کنترل داشته باشیم، میتوانیم از
🔹 مثال ساده
حالا:
خروجی:
🔹 چرا Setter مفید است؟
میتوانیم قبل از ذخیره مقدار، آن را اعتبارسنجی کنیم.
مثلاً سن نباید منفی باشد:
استفاده:
خروجی:
اما:
باعث خطای:
میشود.
🔹 چرا از
اگر داخل Setter بنویسیم:
Setter دوباره خودش را صدا میزند و وارد یک حلقهی بازگشتی میشود.
به همین دلیل مقدار اصلی را در ویژگی دیگری مانند:
ذخیره میکنیم.
🧠 خلاصه
Getter:
برای خواندن مقدار است.
Setter:
برای تغییر مقدار است.
به این ترتیب میتوانیم هنگام تغییر ویژگی، قوانین و اعتبارسنجیهای موردنظرمان را اجرا کنیم.
🎯 تمرین
کلاس
باید این کد:
خروجی:
و این کد:
خطای
✅ پاسخ کامل تمرین
خروجی:
اگر مقدار منفی وارد کنیم:
خروجی خطا خواهد بود:
در این مثال:
در
سپس Getter مقدار ذخیرهشده در:
را برمیگرداند.
پست ۱۰۲ از دوره جامع Python 🐍
تغییر مقدار ویژگی با
@property و Setterدر پست قبل یاد گرفتیم با
@property میتوانیم یک مقدار را مثل ویژگی بخوانیم.اما اگر بخواهیم هنگام تغییر مقدار هم کنترل داشته باشیم، میتوانیم از
setter استفاده کنیم.🔹 مثال ساده
class Person:
def __init__(self, age):
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
self._age = value
حالا:
person = Person(20)
print(person.age)
person.age = 25
print(person.age)
خروجی:
20
25
🔹 چرا Setter مفید است؟
میتوانیم قبل از ذخیره مقدار، آن را اعتبارسنجی کنیم.
مثلاً سن نباید منفی باشد:
class Person:
def __init__(self, age):
self.age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if value < 0:
raise ValueError("Age cannot be negative")
self._age = value
استفاده:
person = Person(20)
person.age = 30
print(person.age)
خروجی:
30
اما:
person.age = -5
باعث خطای:
ValueError: Age cannot be negative
میشود.
🔹 چرا از
_age استفاده کردیم؟اگر داخل Setter بنویسیم:
self.age = value
Setter دوباره خودش را صدا میزند و وارد یک حلقهی بازگشتی میشود.
به همین دلیل مقدار اصلی را در ویژگی دیگری مانند:
self._age
ذخیره میکنیم.
🧠 خلاصه
Getter:
@property
def age(self):
return self._age
برای خواندن مقدار است.
Setter:
@age.setter
def age(self, value):
self._age = value
برای تغییر مقدار است.
به این ترتیب میتوانیم هنگام تغییر ویژگی، قوانین و اعتبارسنجیهای موردنظرمان را اجرا کنیم.
🎯 تمرین
کلاس
Product را طوری کامل کن که قیمت محصول نمیتواند منفی باشد:class Product:
def __init__(self, price):
self.price = price
@property
def price(self):
# کد اینجا
@price.setter
def price(self, value):
# کد اینجا
باید این کد:
product = Product(100)
product.price = 150
print(product.price)
خروجی:
150
و این کد:
product.price = -20
خطای
ValueError ایجاد کند.✅ پاسخ کامل تمرین
class Product:
def __init__(self, price):
self.price = price
@property
def price(self):
return self._price
@price.setter
def price(self, value):
if value < 0:
raise ValueError("Price cannot be negative")
self._price = value
product = Product(100)
print(product.price)
product.price = 150
print(product.price)
خروجی:
100
150
اگر مقدار منفی وارد کنیم:
product.price = -20
خروجی خطا خواهد بود:
ValueError: Price cannot be negative
در این مثال:
self.price = price
در
__init__ باعث میشود Setter نیز برای مقدار اولیه اجرا شود.سپس Getter مقدار ذخیرهشده در:
self._price
را برمیگرداند.
پست ۱۰۲ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۰۳
حذف ویژگی با
در پست قبل یاد گرفتیم با
حالا میتوانیم عملیات حذف آن ویژگی را هم کنترل کنیم.
برای این کار از
🔹 مثال ساده
حالا:
قبل از حذف:
بعد از:
ویژگی
🔹 چرا Deleter مفید است؟
گاهی نمیخواهیم یک ویژگی بدون کنترل حذف شود.
مثلاً میتوانیم هنگام حذف، یک عملیات اضافی انجام دهیم:
استفاده:
خروجی:
🔹 سه بخش یک Property
حالا میتوانیم یک
اینجا:
🔹 استفاده
در اینجا هر سه عملیات توسط
⚠️ نکته مهم
بعد از:
دیگر
بنابراین اگر دوباره بنویسیم:
با خطای
🧠 خلاصه
یک
برای خواندن
برای تغییر
برای حذف
🎯 تمرین
کلاس
سپس این کد را اجرا کن:
پست ۱۰۳ از دوره جامع Python 🐍
حذف ویژگی با
@property و deleterدر پست قبل یاد گرفتیم با
setter میتوانیم تغییر مقدار یک ویژگی را کنترل کنیم.حالا میتوانیم عملیات حذف آن ویژگی را هم کنترل کنیم.
برای این کار از
@property همراه با deleter استفاده میکنیم.🔹 مثال ساده
class Person:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.deleter
def name(self):
del self._name
حالا:
person = Person("Ali")
print(person.name)
del person.nameقبل از حذف:
Ali
بعد از:
del person.name
ویژگی
_name از شیء حذف میشود.🔹 چرا Deleter مفید است؟
گاهی نمیخواهیم یک ویژگی بدون کنترل حذف شود.
مثلاً میتوانیم هنگام حذف، یک عملیات اضافی انجام دهیم:
class User:
def __init__(self, username):
self._username = username
@property
def username(self):
return self._username
@username.deleter
def username(self):
print("Username deleted")
del self._username
استفاده:
user = User("Ali")
print(user.username)
del user.usernameخروجی:
Ali
Username deleted
🔹 سه بخش یک Property
حالا میتوانیم یک
property کامل داشته باشیم:class Product:
def __init__(self, price):
self._price = price
@property
def price(self):
return self._price
@price.setter
def price(self, value):
if value < 0:
raise ValueError("Price cannot be negative")
self._price = value
@price.deleter
def price(self):
del self._price
اینجا:
@property → خواندن
@price.setter → تغییر
@price.deleter → حذف
🔹 استفاده
product = Product(100)
print(product.price)
product.price = 200
print(product.price)
del product.price
در اینجا هر سه عملیات توسط
property کنترل میشوند.⚠️ نکته مهم
بعد از:
del product.price
دیگر
_price وجود ندارد.بنابراین اگر دوباره بنویسیم:
print(product.price)
با خطای
AttributeError مواجه میشویم.🧠 خلاصه
یک
property میتواند سه رفتار داشته باشد:@property
def value(self):
...
برای خواندن
@value.setter
def value(self, new_value):
...
برای تغییر
@value.deleter
def value(self):
...
برای حذف
🎯 تمرین
کلاس
Account را کامل کن تا ویژگی username قابلیت خواندن، تغییر و حذف داشته باشد:class Account:
def __init__(self, username):
self._username = username
@property
def username(self):
# کد اینجا
@username.setter
def username(self, value):
# کد اینجا
@username.deleter
def username(self):
# کد اینجا
سپس این کد را اجرا کن:
account = Account("Ali")
print(account.username)
account.username = "Reza"
print(account.username)
del account.usernameپست ۱۰۳ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۰۴
نمایش بهتر اشیاء با
حالا که با کلاسها و
به طور پیشفرض اگر یک شیء را چاپ کنیم، Python اطلاعاتی شبیه آدرس آن شیء نمایش میدهد.
برای کنترل این رفتار از دو متد ویژه استفاده میکنیم:
🔹
حالا:
خروجی:
🔹 اگر
مثلاً:
خروجی شبیه این خواهد بود:
این خروجی برای کاربر چندان مفید نیست.
با
🔹
حالا:
خروجی:
🔹 تفاوت
به ترتیب:
پس:
⚠️ نکته مهم
اگر
اما
🧠 خلاصه
برای:
و:
برای:
🎯 تمرین
کلاس زیر را کامل کن:
طوری بنویس که:
خروجی شبیه این باشد:
✅ پاسخ کامل تمرین
خروجی:
در
نمایش خوانا و مناسب برای کاربر ساخته میشود.
در
نمایش دقیقتری از نوع شیء و مقادیر آن ایجاد میکنیم.
پست ۱۰۴ از دوره جامع Python 🐍
نمایش بهتر اشیاء با
__str__ و __repr__حالا که با کلاسها و
@property آشنا شدیم، میخواهیم نحوه نمایش Objectها را کنترل کنیم.به طور پیشفرض اگر یک شیء را چاپ کنیم، Python اطلاعاتی شبیه آدرس آن شیء نمایش میدهد.
برای کنترل این رفتار از دو متد ویژه استفاده میکنیم:
__str__
__repr__
🔹
__str____str__ مشخص میکند وقتی شیء را با print() نمایش میدهیم، چه متنی نشان داده شود.class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"{self.name} - {self.age} years old"
حالا:
person = Person("Ali", 25)
print(person)خروجی:
Ali - 25 years old
🔹 اگر
__str__ نداشته باشیممثلاً:
class Person:
def __init__(self, name):
self.name = name
person = Person("Ali")
print(person)
خروجی شبیه این خواهد بود:
<__main__.Person object at 0x...>
این خروجی برای کاربر چندان مفید نیست.
با
__str__ میتوانیم نمایش خواناتری داشته باشیم.🔹
__repr____repr__ برای ارائه یک نمایش دقیقتر و مناسب برای توسعهدهنده از شیء استفاده میشود.class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"{self.name} ({self.age})"
def __repr__(self):
return f"Person(name={self.name!r}, age={self.age!r})"
حالا:
person = Person("Ali", 25)
print(person)
print(repr(person))خروجی:
Ali (25)
Person(name='Ali', age=25)
🔹 تفاوت
str() و repr()print(str(person))
print(repr(person))
به ترتیب:
Ali (25)
Person(name='Ali', age=25)
پس:
str → نمایش خواناتر برای کاربر
repr → نمایش دقیقتر برای توسعهدهنده
⚠️ نکته مهم
اگر
__str__ را تعریف نکرده باشیم، Python در بسیاری از موارد برای نمایش شیء میتواند از __repr__ استفاده کند.اما
__str__ و __repr__ هدف یکسانی ندارند:__str__ → نمایش دوستانه و قابلخواندن__repr__ → نمایش دقیقتر و مناسب توسعه و دیباگ🧠 خلاصه
def __str__(self):
return "..."
برای:
print(object)
و:
def __repr__(self):
return "..."
برای:
repr(object)
🎯 تمرین
کلاس زیر را کامل کن:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __str__(self):
# کد اینجا
def __repr__(self):
# کد اینجا
طوری بنویس که:
product = Product("Laptop", 1200)
print(product)
print(repr(product))خروجی شبیه این باشد:
Laptop - $1200
Product(name='Laptop', price=1200)
✅ پاسخ کامل تمرین
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __str__(self):
return f"{self.name} - ${self.price}"
def __repr__(self):
return f"Product(name={self.name!r}, price={self.price!r})"
product = Product("Laptop", 1200)
print(product)
print(repr(product))
خروجی:
Laptop - $1200
Product(name='Laptop', price=1200)
در
__str__:return f"{self.name} - ${self.price}"نمایش خوانا و مناسب برای کاربر ساخته میشود.
در
__repr__:return f"Product(name={self.name!r}, price={self.price!r})"نمایش دقیقتری از نوع شیء و مقادیر آن ایجاد میکنیم.
پست ۱۰۴ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۰۵
تعیین طول شیء با
در پست قبل با
حالا یکی دیگر از متدهای جادویی (Magic Methods) را یاد میگیریم:
این متد مشخص میکند وقتی از
🔹 استفاده از
مثلاً میتوانیم برای یک کلاس
حالا:
خروجی:
🔹 چرا
Python نمیداند طول یک شیء ساختهشده از کلاس ما چقدر است.
با تعریف:
مشخص میکنیم
مثلاً:
خروجی:
⚠️ نکته مهم
مثلاً این اشتباه است:
چون
🔹 ارتباط با
یک نکته جالب:
اگر کلاس
خروجی:
چون طول شیء
اگر عضو داشته باشیم:
خروجی:
🎯 تمرین
کلاس
خروجی مورد انتظار:
پست ۱۰۵ از دوره جامع Python 🐍
تعیین طول شیء با
__len__در پست قبل با
__str__ و __repr__ آشنا شدیم.حالا یکی دیگر از متدهای جادویی (Magic Methods) را یاد میگیریم:
__len__
این متد مشخص میکند وقتی از
len() روی یک شیء استفاده میکنیم، چه مقداری برگردانده شود.🔹 استفاده از
__len__مثلاً میتوانیم برای یک کلاس
Playlist تعداد آهنگها را مشخص کنیم:class Playlist:
def __init__(self, songs):
self.songs = songs
def __len__(self):
return len(self.songs)
حالا:
playlist = Playlist(["Song 1", "Song 2", "Song 3"])
print(len(playlist))
خروجی:
3
🔹 چرا
__len__؟Python نمیداند طول یک شیء ساختهشده از کلاس ما چقدر است.
با تعریف:
def __len__(self):
مشخص میکنیم
len() چگونه مقدار طول را محاسبه کند.مثلاً:
class Team:
def __init__(self, members):
self.members = members
def __len__(self):
return len(self.members)
team = Team(["Ali", "Sara", "Reza", "Mina"])
print(len(team))
خروجی:
4
⚠️ نکته مهم
__len__ باید یک عدد صحیح (int) غیرمنفی برگرداند.مثلاً این اشتباه است:
def __len__(self):
return "5"
چون
"5" یک رشته است، نه عدد.🔹 ارتباط با
boolیک نکته جالب:
اگر کلاس
__bool__ نداشته باشد، Python میتواند از __len__ برای تعیین True یا False بودن شیء استفاده کند.class Team:
def __init__(self, members):
self.members = members
def __len__(self):
return len(self.members)
team = Team([])
print(bool(team))
خروجی:
False
چون طول شیء
0 است.اگر عضو داشته باشیم:
team = Team(["Ali"])
print(bool(team))
خروجی:
True
🎯 تمرین
کلاس
Cart را کامل کن تا len() تعداد محصولات سبد خرید را برگرداند:class Cart:
def __init__(self, products):
self.products = products
def __len__(self):
# کد اینجا
cart = Cart(["Laptop", "Mouse", "Keyboard"])
print(len(cart))
خروجی مورد انتظار:
3
پست ۱۰۵ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۰۶
مقایسه اشیاء با
تا اینجا دیدیم چطور رفتار شیء را با متدهایی مثل
حالا میخواهیم مشخص کنیم دو شیء چه زمانی برابر محسوب میشوند.
برای این کار از متد جادویی زیر استفاده میکنیم:
🔹
وقتی از
مثلاً:
حالا:
خروجی:
چون
🔹 اگر مقدارها متفاوت باشند
خروجی:
🔹 چرا این متد مهم است؟
بدون پیادهسازی
در این حالت نتیجه معمولاً:
است؛ چون
🔹 پارامتر
در این متد:
مثلاً:
تقریباً به این شکل بررسی میشود:
⚠️ نکته مهم
باید مراقب نوع
مثلاً این کد:
ممکن است باعث خطا شود، چون
یک روش امنتر:
🎯 تمرین
کلاس
خروجی مورد انتظار:
✅ پاسخ کامل تمرین
خروجی:
در این قسمت:
نام کاربری دو شیء را مقایسه میکنیم.
و در این قسمت:
سن دو شیء را مقایسه میکنیم.
در نهایت با
پست ۱۰۶ از دوره جامع Python 🐍
مقایسه اشیاء با
__eq__تا اینجا دیدیم چطور رفتار شیء را با متدهایی مثل
__str__ و __len__ کنترل کنیم.حالا میخواهیم مشخص کنیم دو شیء چه زمانی برابر محسوب میشوند.
برای این کار از متد جادویی زیر استفاده میکنیم:
__eq__
🔹
__eq__ چیست؟وقتی از
== استفاده میکنیم، Python میتواند از __eq__ برای مقایسه دو شیء استفاده کند.مثلاً:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __eq__(self, other):
return self.name == other.name and self.price == other.price
حالا:
product1 = Product("Laptop", 1200)
product2 = Product("Laptop", 1200)
print(product1 == product2)خروجی:
True
چون
name و price هر دو برابر هستند.🔹 اگر مقدارها متفاوت باشند
product1 = Product("Laptop", 1200)
product2 = Product("Laptop", 1500)
print(product1 == product2)خروجی:
False
🔹 چرا این متد مهم است؟
بدون پیادهسازی
__eq__، دو شیء مستقل معمولاً فقط به دلیل اینکه مقادیر مشابهی دارند، برابر در نظر گرفته نمیشوند.class Product:
def __init__(self, name, price):
self.name = name
self.price = price
product1 = Product("Laptop", 1200)
product2 = Product("Laptop", 1200)
print(product1 == product2)
در این حالت نتیجه معمولاً:
False
است؛ چون
product1 و product2 دو شیء جداگانه هستند.🔹 پارامتر
otherدر این متد:
def __eq__(self, other):
self به شیء سمت چپ و other به شیء سمت راست مقایسه اشاره میکند.مثلاً:
product1 == product2
تقریباً به این شکل بررسی میشود:
product1.__eq__(product2)
⚠️ نکته مهم
باید مراقب نوع
other باشیم.مثلاً این کد:
product == 100
ممکن است باعث خطا شود، چون
100 ویژگیهای name و price را ندارد.یک روش امنتر:
def __eq__(self, other):
if not isinstance(other, Product):
return NotImplemented
return self.name == other.name and self.price == other.price
NotImplemented به Python میگوید این مقایسه را با این نوع شیء نمیتوانیم انجام دهیم.🎯 تمرین
کلاس
User را طوری کامل کن که دو کاربر وقتی username و age یکسان دارند، برابر محسوب شوند:class User:
def __init__(self, username, age):
self.username = username
self.age = age
def __eq__(self, other):
# کد اینجا
user1 = User("ali", 25)
user2 = User("ali", 25)
user3 = User("sara", 25)
print(user1 == user2)
print(user1 == user3)
خروجی مورد انتظار:
True
False
✅ پاسخ کامل تمرین
class User:
def __init__(self, username, age):
self.username = username
self.age = age
def __eq__(self, other):
if not isinstance(other, User):
return NotImplemented
return (
self.username == other.username
and self.age == other.age
)
user1 = User("ali", 25)
user2 = User("ali", 25)
user3 = User("sara", 25)
print(user1 == user2)
print(user1 == user3)
خروجی:
True
False
در این قسمت:
self.username == other.username
نام کاربری دو شیء را مقایسه میکنیم.
و در این قسمت:
self.age == other.age
سن دو شیء را مقایسه میکنیم.
در نهایت با
and هر دو شرط باید True باشند تا دو کاربر برابر محسوب شوند.پست ۱۰۶ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۰۷
مقایسه اشیاء با
در پست قبل یاد گرفتیم با
حالا میخواهیم رفتار عملگر
برای این کار از:
استفاده میکنیم.
🔹
یعنی:
مثلاً میتوانیم محصولات را بر اساس قیمت مقایسه کنیم:
حالا:
خروجی:
چون:
🔹 مقایسه برعکس
خروجی:
چون:
صحیح نیست.
🔹
وقتی مینویسیم:
Python تقریباً این متد را فراخوانی میکند:
بنابراین:
به
به
⚠️ نکته مهم
یعنی با تعریف آن، لزوماً تمام عملگرهای مقایسهای دیگر (
هرکدام از این رفتارها متدهای ویژه مربوط به خودشان را دارند.
🔹 مثال کاربردی
میتوانیم دانشآموزها را بر اساس نمره مقایسه کنیم:
خروجی:
چون نمره
🎯 تمرین
کلاس
خروجی مورد انتظار:
پست ۱۰۷ از دوره جامع Python 🐍
مقایسه اشیاء با
__lt__در پست قبل یاد گرفتیم با
__eq__ مشخص کنیم دو شیء چه زمانی برابر هستند.حالا میخواهیم رفتار عملگر
< را برای اشیای کلاس خودمان تعریف کنیم.برای این کار از:
__lt__
استفاده میکنیم.
🔹
__lt__ چیست؟__lt__ مخفف Less Than است.یعنی:
<
مثلاً میتوانیم محصولات را بر اساس قیمت مقایسه کنیم:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __lt__(self, other):
return self.price < other.price
حالا:
product1 = Product("Mouse", 20)
product2 = Product("Keyboard", 50)
print(product1 < product2)خروجی:
True
چون:
20 < 50
🔹 مقایسه برعکس
print(product2 < product1)
خروجی:
False
چون:
50 < 20
صحیح نیست.
🔹
__lt__ چگونه اجرا میشود؟وقتی مینویسیم:
product1 < product2
Python تقریباً این متد را فراخوانی میکند:
product1.__lt__(product2)
بنابراین:
self
به
product1 و:other
به
product2 اشاره میکند.⚠️ نکته مهم
__lt__ فقط رفتار < را تعریف میکند.یعنی با تعریف آن، لزوماً تمام عملگرهای مقایسهای دیگر (
>, <=, >=) را برای کلاس تعریف نکردهایم.هرکدام از این رفتارها متدهای ویژه مربوط به خودشان را دارند.
🔹 مثال کاربردی
میتوانیم دانشآموزها را بر اساس نمره مقایسه کنیم:
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __lt__(self, other):
return self.score < other.score
student1 = Student("Ali", 15)
student2 = Student("Sara", 18)
print(student1 < student2)
خروجی:
True
چون نمره
Ali کمتر از نمره Sara است.🎯 تمرین
کلاس
Book را کامل کن تا دو کتاب بر اساس قیمت با < مقایسه شوند:class Book:
def __init__(self, title, price):
self.title = title
self.price = price
def __lt__(self, other):
# کد اینجا
book1 = Book("Python", 30)
book2 = Book("Django", 45)
print(book1 < book2)
print(book2 < book1)
خروجی مورد انتظار:
True
False
پست ۱۰۷ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۰۸
مقایسه اشیاء با
در پست قبل با
حالا نوبت عملگر بزرگتر است:
برای تعریف این رفتار از متد جادویی:
استفاده میکنیم.
🔹
مثلاً میتوانیم محصولات را بر اساس قیمت مقایسه کنیم:
حالا:
خروجی:
چون:
🔹 مقایسه برعکس
خروجی:
چون:
صحیح نیست.
🔹
وقتی مینویسیم:
Python از متد مقایسهای مربوط به این عملگر استفاده میکند؛ در حالت معمول:
بنابراین:
به شیء سمت چپ و:
به شیء سمت راست اشاره میکند.
🔹 مثال با دانشآموز
خروجی:
چون نمره
⚠️ نکته مهم
را برای کلاس تعریف میکند.
برای عملگرهایی مانند:
متدهای مقایسهای دیگری وجود دارند.
در ادامه با آنها آشنا میشویم.
🎯 تمرین
کلاس
خروجی مورد انتظار:
پست ۱۰۸ از دوره جامع Python 🐍
مقایسه اشیاء با
__gt__در پست قبل با
__lt__ یاد گرفتیم رفتار عملگر < را برای اشیای کلاس خودمان تعریف کنیم.حالا نوبت عملگر بزرگتر است:
>
برای تعریف این رفتار از متد جادویی:
__gt__
استفاده میکنیم.
🔹
__gt__ چیست؟__gt__ مخفف Greater Than است.مثلاً میتوانیم محصولات را بر اساس قیمت مقایسه کنیم:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __gt__(self, other):
return self.price > other.price
حالا:
product1 = Product("Laptop", 1200)
product2 = Product("Mouse", 50)
print(product1 > product2)خروجی:
True
چون:
1200 > 50
🔹 مقایسه برعکس
print(product2 > product1)
خروجی:
False
چون:
50 > 1200
صحیح نیست.
🔹
__gt__ چگونه اجرا میشود؟وقتی مینویسیم:
product1 > product2
Python از متد مقایسهای مربوط به این عملگر استفاده میکند؛ در حالت معمول:
product1.__gt__(product2)
بنابراین:
self
به شیء سمت چپ و:
other
به شیء سمت راست اشاره میکند.
🔹 مثال با دانشآموز
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __gt__(self, other):
return self.score > other.score
student1 = Student("Ali", 18)
student2 = Student("Sara", 15)
print(student1 > student2)
خروجی:
True
چون نمره
18 از 15 بیشتر است.⚠️ نکته مهم
__gt__ فقط رفتار عملگر:>
را برای کلاس تعریف میکند.
برای عملگرهایی مانند:
< <= >=
متدهای مقایسهای دیگری وجود دارند.
در ادامه با آنها آشنا میشویم.
🎯 تمرین
کلاس
Car را کامل کن تا خودروها بر اساس قیمت با > مقایسه شوند:class Car:
def __init__(self, model, price):
self.model = model
self.price = price
def __gt__(self, other):
# کد اینجا
car1 = Car("BMW", 50000)
car2 = Car("Toyota", 30000)
print(car1 > car2)
print(car2 > car1)
خروجی مورد انتظار:
True
False
پست ۱۰۸ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۰۹
مقایسه اشیاء با
در دو پست قبل با:
رفتار
حالا دو عملگر دیگر را یاد میگیریم:
🔹
یعنی:
مثلاً:
حالا:
خروجی:
چون:
صحیح است.
🔹
یعنی:
مثلاً:
حالا:
خروجی:
چون:
صحیح است.
🔹 یک مثال کامل
میتوانیم هر دو متد را در یک کلاس داشته باشیم:
خروجی:
چون نمره هر دو دانشآموز
🧠 متدهای مقایسهای مهم
تا اینجا با این متدها آشنا شدیم:
این متدها به Python میگویند عملگرهای مقایسهای با اشیای کلاس ما چگونه رفتار کنند.
🎯 تمرین
کلاس
خروجی مورد انتظار:
✅ پاسخ کامل تمرین
خروجی:
در این قسمت:
قیمت کتاب سمت چپ با قیمت کتاب سمت راست مقایسه میشود.
و در:
برعکس، بررسی میکنیم که قیمت کتاب سمت چپ بزرگتر یا مساوی قیمت کتاب سمت راست باشد.
پست ۱۰۹ از دوره جامع Python 🐍
مقایسه اشیاء با
__le__ و __ge__در دو پست قبل با:
__lt__
__gt__
رفتار
< و > را برای اشیای کلاس تعریف کردیم.حالا دو عملگر دیگر را یاد میگیریم:
<=
>=
🔹
__le____le__ مخفف Less Than or Equal است.یعنی:
کوچکتر یا مساوی
مثلاً:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __le__(self, other):
return self.price <= other.price
حالا:
product1 = Product("Mouse", 50)
product2 = Product("Keyboard", 50)
print(product1 <= product2)خروجی:
True
چون:
50 <= 50
صحیح است.
🔹
__ge____ge__ مخفف Greater Than or Equal است.یعنی:
بزرگتر یا مساوی
مثلاً:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __ge__(self, other):
return self.price >= other.price
حالا:
product1 = Product("Laptop", 1200)
product2 = Product("Mouse", 50)
print(product1 >= product2)خروجی:
True
چون:
1200 >= 50
صحیح است.
🔹 یک مثال کامل
میتوانیم هر دو متد را در یک کلاس داشته باشیم:
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __le__(self, other):
return self.score <= other.score
def __ge__(self, other):
return self.score >= other.score
student1 = Student("Ali", 18)
student2 = Student("Sara", 18)
print(student1 <= student2)
print(student1 >= student2)
خروجی:
True
True
چون نمره هر دو دانشآموز
18 است.🧠 متدهای مقایسهای مهم
تا اینجا با این متدها آشنا شدیم:
__eq__ → ==
__lt__ → <
__gt__ → >
__le__ → <=
__ge__ → >=
این متدها به Python میگویند عملگرهای مقایسهای با اشیای کلاس ما چگونه رفتار کنند.
🎯 تمرین
کلاس
Book را کامل کن تا دو کتاب بر اساس قیمت با <= و >= مقایسه شوند:class Book:
def __init__(self, title, price):
self.title = title
self.price = price
def __le__(self, other):
# کد اینجا
def __ge__(self, other):
# کد اینجا
book1 = Book("Python", 30)
book2 = Book("Django", 45)
print(book1 <= book2)
print(book1 >= book2)
خروجی مورد انتظار:
True
False
✅ پاسخ کامل تمرین
class Book:
def __init__(self, title, price):
self.title = title
self.price = price
def __le__(self, other):
return self.price <= other.price
def __ge__(self, other):
return self.price >= other.price
book1 = Book("Python", 30)
book2 = Book("Django", 45)
print(book1 <= book2)
print(book1 >= book2)
خروجی:
True
False
در این قسمت:
return self.price <= other.price
قیمت کتاب سمت چپ با قیمت کتاب سمت راست مقایسه میشود.
و در:
return self.price >= other.price
برعکس، بررسی میکنیم که قیمت کتاب سمت چپ بزرگتر یا مساوی قیمت کتاب سمت راست باشد.
پست ۱۰۹ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۱۰
بررسی نابرابری اشیاء با
در پستهای قبل با متدهای مقایسهای مختلف آشنا شدیم.
حالا میخواهیم رفتار عملگر:
را برای اشیای کلاس خودمان تعریف کنیم.
برای این کار از متد جادویی:
استفاده میکنیم.
🔹
یعنی بررسی میکند آیا دو شیء با هم متفاوت هستند یا نه.
مثلاً:
حالا:
خروجی:
چون قیمت دو محصول متفاوت است.
🔹 وقتی هر دو مقدار یکسان باشند
خروجی:
چون دو محصول از نظر
🔹
وقتی مینویسیم:
Python میتواند متد زیر را فراخوانی کند:
بنابراین:
⚠️ نکته مهم
در مثال بالا از
چون اگر حتی یکی از این دو مقدار متفاوت باشد، دو محصول متفاوت محسوب میشوند.
مثلاً:
🧠 متدهای مقایسهای تا اینجا
با این متدها میتوانیم رفتار اصلی عملگرهای مقایسهای را برای کلاس خودمان تعریف کنیم.
🎯 تمرین
کلاس
خروجی مورد انتظار:
✅ پاسخ کامل تمرین
خروجی:
در این قسمت:
نام کاربری دو شیء مقایسه میشود.
و:
سن دو شیء مقایسه میشود.
از
پست ۱۱۰ از دوره جامع Python 🐍
بررسی نابرابری اشیاء با
__ne__در پستهای قبل با متدهای مقایسهای مختلف آشنا شدیم.
حالا میخواهیم رفتار عملگر:
!=
را برای اشیای کلاس خودمان تعریف کنیم.
برای این کار از متد جادویی:
__ne__
استفاده میکنیم.
🔹
__ne__ چیست؟__ne__ مخفف Not Equal است.یعنی بررسی میکند آیا دو شیء با هم متفاوت هستند یا نه.
مثلاً:
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def __ne__(self, other):
return (
self.name != other.name
or self.price != other.price
)
حالا:
product1 = Product("Laptop", 1200)
product2 = Product("Laptop", 1500)
print(product1 != product2)خروجی:
True
چون قیمت دو محصول متفاوت است.
🔹 وقتی هر دو مقدار یکسان باشند
product1 = Product("Laptop", 1200)
product2 = Product("Laptop", 1200)
print(product1 != product2)خروجی:
False
چون دو محصول از نظر
name و price یکسان هستند.🔹
__ne__ چگونه اجرا میشود؟وقتی مینویسیم:
product1 != product2
Python میتواند متد زیر را فراخوانی کند:
product1.__ne__(product2)
بنابراین:
self → شیء سمت چپ
other → شیء سمت راست
⚠️ نکته مهم
در مثال بالا از
or استفاده کردیم:self.name != other.name or self.price != other.price
چون اگر حتی یکی از این دو مقدار متفاوت باشد، دو محصول متفاوت محسوب میشوند.
مثلاً:
name یکسان + price متفاوت → True
name متفاوت + price یکسان → True
name متفاوت + price متفاوت → True
name یکسان + price یکسان → False
🧠 متدهای مقایسهای تا اینجا
__eq__ → ==
__ne__ → !=
__lt__ → <
__gt__ → >
__le__ → <=
__ge__ → >=
با این متدها میتوانیم رفتار اصلی عملگرهای مقایسهای را برای کلاس خودمان تعریف کنیم.
🎯 تمرین
کلاس
User را کامل کن تا دو کاربر وقتی username یا age متفاوت دارند، متفاوت محسوب شوند:class User:
def __init__(self, username, age):
self.username = username
self.age = age
def __ne__(self, other):
# کد اینجا
user1 = User("ali", 25)
user2 = User("ali", 25)
user3 = User("sara", 25)
print(user1 != user2)
print(user1 != user3)
خروجی مورد انتظار:
False
True
✅ پاسخ کامل تمرین
class User:
def __init__(self, username, age):
self.username = username
self.age = age
def __ne__(self, other):
if not isinstance(other, User):
return NotImplemented
return (
self.username != other.username
or self.age != other.age
)
user1 = User("ali", 25)
user2 = User("ali", 25)
user3 = User("sara", 25)
print(user1 != user2)
print(user1 != user3)
خروجی:
False
True
در این قسمت:
self.username != other.username
نام کاربری دو شیء مقایسه میشود.
و:
self.age != other.age
سن دو شیء مقایسه میشود.
از
or استفاده میکنیم، چون متفاوت بودن حتی یکی از ویژگیها کافی است تا دو کاربر متفاوت محسوب شوند.پست ۱۱۰ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۱۱
کنترل عملگر
تا اینجا چندین Magic Method برای کنترل رفتار اشیاء یاد گرفتیم.
حالا میخواهیم مشخص کنیم وقتی از عملگر:
برای یک شیء استفاده میکنیم، Python چگونه بررسی کند که یک مقدار داخل آن شیء وجود دارد یا نه.
برای این کار از:
استفاده میکنیم.
🔹
این متد رفتار عملگر
مثلاً یک کلاس
حالا:
خروجی:
🔹
وقتی
خروجی:
🔹
وقتی مینویسیم:
Python از رفتار تعریفشده در:
استفاده میکند.
در این متد:
پارامتر
🔹 مثال با
میتوانیم بررسی کنیم آیا یک نام کاربری در گروه وجود دارد یا نه:
خروجی:
⚠️ نکته مهم
یا:
در واقع میتوانیم منطق بررسی را کاملاً مطابق نیاز کلاس خودمان تعریف کنیم.
🧠 چند Magic Method مهم تا اینجا
این متدها به ما اجازه میدهند رفتار طبیعی Python را برای کلاسهای خودمان شخصیسازی کنیم.
🎯 تمرین
کلاس
خروجی مورد انتظار:
پست ۱۱۱ از دوره جامع Python 🐍
کنترل عملگر
in با __contains__تا اینجا چندین Magic Method برای کنترل رفتار اشیاء یاد گرفتیم.
حالا میخواهیم مشخص کنیم وقتی از عملگر:
in
برای یک شیء استفاده میکنیم، Python چگونه بررسی کند که یک مقدار داخل آن شیء وجود دارد یا نه.
برای این کار از:
__contains__
استفاده میکنیم.
🔹
__contains__ چیست؟این متد رفتار عملگر
in را برای شیء مشخص میکند.مثلاً یک کلاس
Playlist میسازیم:class Playlist:
def __init__(self, songs):
self.songs = songs
def __contains__(self, song):
return song in self.songs
حالا:
playlist = Playlist([
"Song A",
"Song B",
"Song C"
])
print("Song B" in playlist)
print("Song X" in playlist)
خروجی:
True
False
🔹
not inوقتی
__contains__ را تعریف کنیم، میتوانیم از not in هم استفاده کنیم:print("Song X" not in playlist)خروجی:
True
🔹
__contains__ چگونه اجرا میشود؟وقتی مینویسیم:
"Song B" in playlist
Python از رفتار تعریفشده در:
playlist.__contains__("Song B")استفاده میکند.
در این متد:
def __contains__(self, song):
پارامتر
song همان مقداری است که میخواهیم وجود آن را بررسی کنیم.🔹 مثال با
UserGroupمیتوانیم بررسی کنیم آیا یک نام کاربری در گروه وجود دارد یا نه:
class UserGroup:
def __init__(self, users):
self.users = users
def __contains__(self, username):
return username in self.users
group = UserGroup(["ali", "sara", "reza"])
print("ali" in group)
print("mina" in group)
خروجی:
True
False
⚠️ نکته مهم
__contains__ باید نتیجهای مناسب برای بررسی وجود داشتن برگرداند؛ معمولاً:True
یا:
False
در واقع میتوانیم منطق بررسی را کاملاً مطابق نیاز کلاس خودمان تعریف کنیم.
🧠 چند Magic Method مهم تا اینجا
__str__ → print()
__repr__ → repr()
__len__ → len()
__eq__ → ==
__ne__ → !=
__lt__ → <
__gt__ → >
__le__ → <=
__ge__ → >=
__contains__ → in
این متدها به ما اجازه میدهند رفتار طبیعی Python را برای کلاسهای خودمان شخصیسازی کنیم.
🎯 تمرین
کلاس
Library را کامل کن تا بتوانیم با in بررسی کنیم آیا یک کتاب در کتابخانه وجود دارد یا نه:class Library:
def __init__(self, books):
self.books = books
def __contains__(self, title):
# کد اینجا
library = Library([
"Python",
"Django",
"Flask"
])
print("Python" in library)
print("Java" in library)
خروجی مورد انتظار:
True
False
پست ۱۱۱ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۱۲
دسترسی به عناصر شیء با
تا اینجا یاد گرفتیم با
حالا میخواهیم کاری کنیم که بتوانیم با استفاده از
برای این کار از
🔹
وقتی Python چنین کدی میبیند:
در واقع میتواند متد زیر را صدا بزند:
🔹 مثال ساده
خروجی:
در اینجا:
باعث میشود Python از
🔹 پشتیبانی از Index منفی
چون در مثال بالا دسترسی نهایی به یک
خروجی:
🔹 پشتیبانی از Slice
خروجی:
چون مقدار
⚠️ نکته مهم
در مثال ما:
دادهها را نگهداری میکند و
🧠 خلاصه
مثلاً:
تقریباً معادل:
است.
🎯 تمرین
کلاس
خروجی مورد انتظار:
پست ۱۱۲ از دوره جامع Python 🐍
دسترسی به عناصر شیء با
__getitem__تا اینجا یاد گرفتیم با
__contains__ رفتار in را برای یک شیء کنترل کنیم.حالا میخواهیم کاری کنیم که بتوانیم با استفاده از
[] به عناصر یک شیء دسترسی داشته باشیم.برای این کار از
__getitem__ استفاده میکنیم.🔹
__getitem__وقتی Python چنین کدی میبیند:
object[index]
در واقع میتواند متد زیر را صدا بزند:
object.__getitem__(index)
🔹 مثال ساده
class Playlist:
def __init__(self, songs):
self.songs = songs
def __getitem__(self, index):
return self.songs[index]
playlist = Playlist([
"Song A",
"Song B",
"Song C"
])
print(playlist[0])
print(playlist[1])
خروجی:
Song A
Song B
در اینجا:
playlist[0]
باعث میشود Python از
__getitem__ استفاده کند.🔹 پشتیبانی از Index منفی
چون در مثال بالا دسترسی نهایی به یک
list انجام میشود، Index منفی هم کار میکند:print(playlist[-1])
خروجی:
Song C
🔹 پشتیبانی از Slice
__getitem__ فقط برای یک Index نیست؛ میتوانیم Slice هم دریافت کنیم:print(playlist[0:2])
خروجی:
['Song A', 'Song B']
چون مقدار
0:2 به عنوان index به __getitem__ ارسال میشود.⚠️ نکته مهم
__getitem__ خودش الزاماً دادهها را نگهداری نمیکند.در مثال ما:
self.songs
دادهها را نگهداری میکند و
__getitem__ فقط نحوه دسترسی به آنها را مشخص میکند.🧠 خلاصه
obj[index]
↓
__getitem__(index)
مثلاً:
playlist[1]
تقریباً معادل:
playlist.__getitem__(1)
است.
🎯 تمرین
کلاس
Library را کامل کن تا بتوانیم با Index به کتابها دسترسی داشته باشیم:class Library:
def __init__(self, books):
self.books = books
def __getitem__(self, index):
# code
library = Library([
"Python",
"Django",
"Flask"
])
print(library[0])
print(library[2])
خروجی مورد انتظار:
Python
Flask
پست ۱۱۲ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۱۳
تغییر عناصر شیء با
در پست قبل یاد گرفتیم با
حالا میخواهیم با همان
برای این کار از
🔹
وقتی Python چنین کدی میبیند:
میتواند متد زیر را اجرا کند:
🔹 مثال ساده
خروجی:
در اینجا:
باعث میشود Python از
🔹 چه اتفاقی میافتد؟
این کد:
تقریباً به این شکل عمل میکند:
و داخل متد:
مقدار داخل لیست تغییر میکند.
🔹 ترکیب
با داشتن هر دو متد، شیء ما میتواند هم خوانده و هم تغییر داده شود:
خروجی:
⚠️ نکته مهم
اما
پس:
🎯 تمرین
کلاس
خروجی مورد انتظار:
✅ پاسخ کامل تمرین
خروجی:
پست ۱۱۳ از دوره جامع Python 🐍
تغییر عناصر شیء با
__setitem__در پست قبل یاد گرفتیم با
__getitem__ کاری کنیم که بتوانیم از [] برای خواندن عناصر یک شیء استفاده کنیم.حالا میخواهیم با همان
[] بتوانیم مقدار یک عنصر را تغییر دهیم.برای این کار از
__setitem__ استفاده میکنیم.🔹
__setitem__وقتی Python چنین کدی میبیند:
object[index] = value
میتواند متد زیر را اجرا کند:
object.__setitem__(index, value)
🔹 مثال ساده
class Playlist:
def __init__(self, songs):
self.songs = songs
def __getitem__(self, index):
return self.songs[index]
def __setitem__(self, index, value):
self.songs[index] = value
playlist = Playlist([
"Song A",
"Song B",
"Song C"
])
playlist[1] = "New Song"
print(playlist[1])
خروجی:
New Song
در اینجا:
playlist[1] = "New Song"
باعث میشود Python از
__setitem__ استفاده کند.🔹 چه اتفاقی میافتد؟
این کد:
playlist[1] = "New Song"
تقریباً به این شکل عمل میکند:
playlist.__setitem__(1, "New Song")
و داخل متد:
self.songs[index] = value
مقدار داخل لیست تغییر میکند.
🔹 ترکیب
__getitem__ و __setitem__با داشتن هر دو متد، شیء ما میتواند هم خوانده و هم تغییر داده شود:
playlist = Playlist([
"Song A",
"Song B",
"Song C"
])
print(playlist[0])
playlist[0] = "Updated Song"
print(playlist[0])
خروجی:
Song A
Updated Song
⚠️ نکته مهم
__getitem__ برای دریافت مقدار است:playlist[0]
اما
__setitem__ برای قرار دادن یا تغییر مقدار است:playlist[0] = "New Song"
پس:
__getitem__ → obj[index]
__setitem__ → obj[index] = value
🎯 تمرین
کلاس
Inventory را کامل کن:class Inventory:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
# code
def __setitem__(self, index, value):
# code
inventory = Inventory([
"Keyboard",
"Mouse",
"Monitor"
])
print(inventory[1])
inventory[1] = "Gaming Mouse"
print(inventory[1])
خروجی مورد انتظار:
Mouse
Gaming Mouse
✅ پاسخ کامل تمرین
class Inventory:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
def __setitem__(self, index, value):
self.items[index] = value
inventory = Inventory([
"Keyboard",
"Mouse",
"Monitor"
])
print(inventory[1])
inventory[1] = "Gaming Mouse"
print(inventory[1])
خروجی:
Mouse
Gaming Mouse
پست ۱۱۳ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۱۴
پیمایش روی شیء با
تا اینجا یاد گرفتیم با
حالا میخواهیم کاری کنیم که بتوانیم مستقیماً روی شیء با
برای این کار از
🔹
وقتی مینویسیم:
Python باید بداند چگونه روی
یکی از روشهای اصلی این کار استفاده از:
است.
🔹 مثال ساده
خروجی:
🔹 چرا
در اینجا:
تابع
سپس
🔹 استفاده با
یک شیء قابل پیمایش را میتوان به لیست هم تبدیل کرد:
خروجی:
🔹 یک مثال دیگر
خروجی:
⚠️ نکته مهم
در مثال ما:
این کار را برای لیست داخلی انجام میدهد.
بنابراین:
🧠 مقایسه تا اینجا
هرکدام رفتار متفاوتی از شیء را کنترل میکنند.
🎯 تمرین
کلاس
خروجی مورد انتظار:
✅ پاسخ کامل تمرین
خروجی:
پست ۱۱۴ از دوره جامع Python 🐍
پیمایش روی شیء با
__iter__تا اینجا یاد گرفتیم با
__getitem__ به عناصر یک شیء دسترسی داشته باشیم.حالا میخواهیم کاری کنیم که بتوانیم مستقیماً روی شیء با
for پیمایش کنیم.برای این کار از
__iter__ استفاده میکنیم.🔹
__iter__وقتی مینویسیم:
for item in object:
print(item)
Python باید بداند چگونه روی
object پیمایش کند.یکی از روشهای اصلی این کار استفاده از:
__iter__()
است.
🔹 مثال ساده
class Playlist:
def __init__(self, songs):
self.songs = songs
def __iter__(self):
return iter(self.songs)
playlist = Playlist([
"Song A",
"Song B",
"Song C"
])
for song in playlist:
print(song)
خروجی:
Song A
Song B
Song C
🔹 چرا
iter()؟در اینجا:
return iter(self.songs)
تابع
iter() از لیست یک iterator میسازد.سپس
for از آن برای گرفتن عناصر یکییکی استفاده میکند.🔹 استفاده با
list()یک شیء قابل پیمایش را میتوان به لیست هم تبدیل کرد:
print(list(playlist))
خروجی:
['Song A', 'Song B', 'Song C']
🔹 یک مثال دیگر
class Team:
def __init__(self, members):
self.members = members
def __iter__(self):
return iter(self.members)
team = Team([
"Ali",
"Sara",
"Reza"
])
for member in team:
print(member)
خروجی:
Ali
Sara
Reza
⚠️ نکته مهم
__iter__ باید یک iterator برگرداند.در مثال ما:
return iter(self.members)
این کار را برای لیست داخلی انجام میدهد.
بنابراین:
__iter__ → امکان پیمایش شیء با for
🧠 مقایسه تا اینجا
__contains__ → in
__getitem__ → obj[index]
__setitem__ → obj[index] = value
__iter__ → for item in obj
هرکدام رفتار متفاوتی از شیء را کنترل میکنند.
🎯 تمرین
کلاس
Library را طوری کامل کن که بتوانیم روی کتابهای آن با for پیمایش کنیم:class Library:
def __init__(self, books):
self.books = books
def __iter__(self):
# code
library = Library([
"Python",
"Django",
"Flask"
])
for book in library:
print(book)
خروجی مورد انتظار:
Python
Django
Flask
✅ پاسخ کامل تمرین
class Library:
def __init__(self, books):
self.books = books
def __iter__(self):
return iter(self.books)
library = Library([
"Python",
"Django",
"Flask"
])
for book in library:
print(book)
خروجی:
Python
Django
Flask
پست ۱۱۴ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۱۵
ساخت Iterator با
در پست قبل با
حالا میخواهیم ببینیم یک Iterator چگونه میتواند عناصر را یکییکی در اختیار Python قرار دهد.
برای این کار از
🔹
هر بار که
خروجی:
بعد از تمام شدن عناصر،
🔹 ساخت Iterator خودمان
میتوانیم کلاسی بسازیم که خودش Iterator باشد:
حالا:
خروجی:
🔹 استفاده با
چون کلاس ما
خروجی:
🔹 چرا
در این مثال:
خود شیء
پس Python همان شیء را برای دریافت مقادیر بعدی استفاده میکند.
🔹 نقش
وقتی دیگر مقداری باقی نمانده باشد:
به Python میگوییم:
🧠 تفاوت
برای ساخت یک Iterator معمولاً هر دو متد را داریم:
🎯 تمرین
کلاس
خروجی مورد انتظار:
✅ پاسخ کامل تمرین
خروجی:
در اینجا:
در هر مرحله عدد را یک واحد کاهش میدهد.
وقتی مقدار به
اجرا میشود و حلقه
پست ۱۱۵ از دوره جامع Python 🐍
ساخت Iterator با
__next__در پست قبل با
__iter__ آشنا شدیم.حالا میخواهیم ببینیم یک Iterator چگونه میتواند عناصر را یکییکی در اختیار Python قرار دهد.
برای این کار از
__next__ استفاده میکنیم.🔹
__next__هر بار که
next() را روی یک Iterator اجرا کنیم، عنصر بعدی را برمیگرداند:numbers = iter([10, 20, 30])
print(next(numbers))
print(next(numbers))
print(next(numbers))
خروجی:
10
20
30
بعد از تمام شدن عناصر،
next() با خطای StopIteration مواجه میشود.🔹 ساخت Iterator خودمان
میتوانیم کلاسی بسازیم که خودش Iterator باشد:
class Counter:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current > self.end:
raise StopIteration
value = self.current
self.current += 1
return value
حالا:
counter = Counter(1, 3)
print(next(counter))
print(next(counter))
print(next(counter))
خروجی:
1
2
3
🔹 استفاده با
forچون کلاس ما
__iter__ و __next__ دارد، میتوانیم از آن با for هم استفاده کنیم:counter = Counter(1, 3)
for number in counter:
print(number)
خروجی:
1
2
3
🔹 چرا
return self؟در این مثال:
def __iter__(self):
return self
خود شیء
Counter همان Iterator است.پس Python همان شیء را برای دریافت مقادیر بعدی استفاده میکند.
🔹 نقش
StopIterationوقتی دیگر مقداری باقی نمانده باشد:
if self.current > self.end:
raise StopIteration
به Python میگوییم:
دیگر عنصری برای پیمایش وجود ندارد.
for این وضعیت را مدیریت میکند و حلقه را متوقف میکند.🧠 تفاوت
__iter__ و __next____iter__ → Iterator را برمیگرداند
__next__ → عنصر بعدی را برمیگرداند
برای ساخت یک Iterator معمولاً هر دو متد را داریم:
__iter__()
__next__()
🎯 تمرین
کلاس
Countdown را کامل کن تا از عدد 3 تا 1 را یکییکی برگرداند:class Countdown:
def __init__(self, start):
self.current = start
def __iter__(self):
# code
def __next__(self):
# code
countdown = Countdown(3)
for number in countdown:
print(number)
خروجی مورد انتظار:
3
2
1
✅ پاسخ کامل تمرین
class Countdown:
def __init__(self, start):
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current < 1:
raise StopIteration
value = self.current
self.current -= 1
return value
countdown = Countdown(3)
for number in countdown:
print(number)
خروجی:
3
2
1
در اینجا:
self.current -= 1
در هر مرحله عدد را یک واحد کاهش میدهد.
وقتی مقدار به
0 برسد:raise StopIteration
اجرا میشود و حلقه
for متوقف میشود.پست ۱۱۵ از دوره جامع Python 🐍
1
🐍 آموزش جامع Python — پست ۱۱۶
ساخت Generator با
در پستهای قبل با Iterator و
Python راه سادهتری برای ساخت Iteratorها دارد: Generator.
برای ساخت Generator معمولاً از
🔹
مثلاً:
حالا:
خروجی:
🔹 Generator Object
تابعی که
🔹 اجرای مرحلهای
Generator مقدارها را یکییکی تولید میکند:
خروجی:
بعد از تمام شدن Generator،
🔹 تفاوت
با
فقط اولین
اما با
مقادیر میتوانند یکییکی تولید شوند.
🔹 چرا Generator مهم است؟
فرض کن میخواهیم اعداد
ساختن یک لیست کامل:
همه مقادیر را در حافظه نگه میدارد.
اما Generator میتواند مقدارها را در زمان نیاز تولید کند:
در این حالت لازم نیست همه مقادیر از ابتدا در یک لیست ذخیره شوند.
این ویژگی برای کار با دادههای بزرگ بسیار مهم است.
🧠 خلاصه
و یک نکته مهم:
🎯 تمرین
یک Generator به نام
خروجی مورد انتظار:
پست ۱۱۶ از دوره جامع Python 🐍
ساخت Generator با
yieldدر پستهای قبل با Iterator و
__next__ آشنا شدیم.Python راه سادهتری برای ساخت Iteratorها دارد: Generator.
برای ساخت Generator معمولاً از
yield استفاده میکنیم.🔹
yield چیست؟yield شبیه return است، اما یک تفاوت مهم دارد:return اجرای تابع را تمام میکند.yield مقدار را برمیگرداند و وضعیت اجرای تابع را حفظ میکند.مثلاً:
def numbers():
yield 1
yield 2
yield 3
حالا:
for number in numbers():
print(number)
خروجی:
1
2
3
🔹 Generator Object
تابعی که
yield دارد، هنگام فراخوانی معمولی، نتیجه را یکجا اجرا نمیکند؛ یک Generator Object برمیگرداند:def numbers():
yield 1
yield 2
yield 3
result = numbers()
print(result)
result یک Generator است.🔹 اجرای مرحلهای
Generator مقدارها را یکییکی تولید میکند:
def numbers():
yield 1
yield 2
yield 3
numbers_generator = numbers()
print(next(numbers_generator))
print(next(numbers_generator))
print(next(numbers_generator))
خروجی:
1
2
3
بعد از تمام شدن Generator،
next() باعث StopIteration میشود.🔹 تفاوت
return و yieldبا
return:def get_number():
return 1
return 2
فقط اولین
return قابل اجراست.اما با
yield:def get_numbers():
yield 1
yield 2
مقادیر میتوانند یکییکی تولید شوند.
🔹 چرا Generator مهم است؟
فرض کن میخواهیم اعداد
1 تا 1,000,000 را تولید کنیم.ساختن یک لیست کامل:
numbers = list(range(1, 1_000_001))
همه مقادیر را در حافظه نگه میدارد.
اما Generator میتواند مقدارها را در زمان نیاز تولید کند:
def numbers():
for i in range(1, 1_000_001):
yield i
در این حالت لازم نیست همه مقادیر از ابتدا در یک لیست ذخیره شوند.
این ویژگی برای کار با دادههای بزرگ بسیار مهم است.
🧠 خلاصه
yield → تولید مقدار بهصورت مرحلهای
Generator → تولیدکننده مقدارها
next() → دریافت مقدار بعدی
StopIteration → پایان Generator
و یک نکته مهم:
هر تابعی که
yieldداشته باشد، یک Generator Function است.
🎯 تمرین
یک Generator به نام
count_up بنویس که اعداد 1 تا 5 را یکییکی تولید کند:def count_up():
# code
for number in count_up():
print(number)
خروجی مورد انتظار:
1
2
3
4
5
پست ۱۱۶ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۱۷
Generator با
در پست قبل دیدیم که
حالا یک مرحله جلوتر میرویم و یاد میگیریم Generator چگونه میتواند با حلقه و دادههای پویا کار کند.
🔹 تولید مقدار با حلقه
بهجای اینکه چند
حالا:
خروجی:
🔹 چرا
در
این اعداد را تولید میکند:
پس برای اینکه
🔹 Generator فقط تا زمانی که لازم است
میتوانیم فقط چند مقدار اول را دریافت کنیم:
خروجی:
در اینجا Generator لازم نیست همه اعداد را از ابتدا تولید کند.
هر بار که
🔹 یک مثال کاربردیتر
فرض کنیم میخواهیم فقط اعداد زوج را تولید کنیم:
حالا:
خروجی:
⚠️ نکته مهم
Generator با
به همین دلیل برای دادههای زیاد میتواند از نظر مصرف حافظه مناسبتر باشد.
🧠 خلاصه
🎯 تمرین
یک Generator به نام
خروجی مورد انتظار:
پست ۱۱۷ از دوره جامع Python 🐍
Generator با
yield و ورودی پویادر پست قبل دیدیم که
yield میتواند مقدارها را یکییکی تولید کند.حالا یک مرحله جلوتر میرویم و یاد میگیریم Generator چگونه میتواند با حلقه و دادههای پویا کار کند.
🔹 تولید مقدار با حلقه
بهجای اینکه چند
yield پشت سر هم بنویسیم، میتوانیم از حلقه استفاده کنیم:def count_up(limit):
for number in range(1, limit + 1):
yield number
حالا:
for number in count_up(5):
print(number)
خروجی:
1
2
3
4
5
🔹 چرا
limit + 1؟در
range() مقدار انتهایی شامل نمیشود:range(1, 5)
این اعداد را تولید میکند:
1
2
3
4
پس برای اینکه
5 هم تولید شود، مینویسیم:range(1, limit + 1)
🔹 Generator فقط تا زمانی که لازم است
میتوانیم فقط چند مقدار اول را دریافت کنیم:
numbers = count_up(100)
print(next(numbers))
print(next(numbers))
print(next(numbers))
خروجی:
1
2
3
در اینجا Generator لازم نیست همه اعداد را از ابتدا تولید کند.
هر بار که
next() اجرا میشود، Generator تا yield بعدی ادامه پیدا میکند.🔹 یک مثال کاربردیتر
فرض کنیم میخواهیم فقط اعداد زوج را تولید کنیم:
def even_numbers(limit):
for number in range(2, limit + 1, 2):
yield number
حالا:
for number in even_numbers(10):
print(number)
خروجی:
2
4
6
8
10
⚠️ نکته مهم
Generator با
yield مقدارها را یکییکی تولید میکند، نه اینکه همه را از ابتدا در یک لیست قرار دهد.به همین دلیل برای دادههای زیاد میتواند از نظر مصرف حافظه مناسبتر باشد.
🧠 خلاصه
yield → تولید مرحلهای مقدار
range → تولید دنباله عددی
next() → دریافت مقدار بعدی
Generator → تولید مقدار در زمان نیاز
🎯 تمرین
یک Generator به نام
odd_numbers بنویس که اعداد فرد از 1 تا 9 را تولید کند:def odd_numbers():
# code
for number in odd_numbers():
print(number)
خروجی مورد انتظار:
1
3
5
7
9
پست ۱۱۷ از دوره جامع Python 🐍
🐍 آموزش جامع Python — پست ۱۱۸
ارسال مقدار به Generator با
در پستهای قبل یاد گرفتیم Generator با
اما
🔹
مثال ساده:
برای شروع Generator ابتدا باید آن را اجرا کنیم:
حالا میتوانیم مقدار ارسال کنیم:
خروجی:
🔹
در این کد:
حالا:
خروجی:
🔹
میتوانیم هم مقدار دریافت کنیم و هم مقدار تولید کنیم:
حالا:
خروجی:
در اینجا:
مقدار
⚠️ نکته مهم
قبل از اولین
تا اولین
این کار Generator را آماده دریافت مقدار میکند.
🧠 خلاصه
Generator فقط یک تولیدکننده ساده نیست؛ میتواند بین کد بیرونی و خودش داده رد و بدل کند.
🎯 تمرین
Generator زیر را کامل کن تا عدد دریافتشده را دو برابر کند:
خروجی مورد انتظار:
✅ پاسخ کامل تمرین
خروجی:
در اینجا ابتدا:
Generator را تا اولین
سپس:
عدد
بنابراین:
و در نهایت:
مقدار
پست ۱۱۸ از دوره جامع Python 🐍
ارسال مقدار به Generator با
send()در پستهای قبل یاد گرفتیم Generator با
yield مقدار تولید میکند.اما
yield فقط برای خروجی گرفتن نیست؛ میتوانیم با send() یک مقدار را به Generator برگردانیم.🔹
send()مثال ساده:
def calculator():
number = yield
print(number)
برای شروع Generator ابتدا باید آن را اجرا کنیم:
calc = calculator()
next(calc)
حالا میتوانیم مقدار ارسال کنیم:
calc.send(10)
خروجی:
10
🔹
yield میتواند مقدار دریافت کنددر این کد:
def calculator():
number = yield
result = number * 2
print(result)
حالا:
calc = calculator()
next(calc)
calc.send(5)
خروجی:
10
🔹
yield هم میتواند مقدار برگرداندمیتوانیم هم مقدار دریافت کنیم و هم مقدار تولید کنیم:
def calculator():
number = yield
result = number * 2
yield result
حالا:
calc = calculator()
next(calc)
result = calc.send(5)
print(result)
خروجی:
10
در اینجا:
calc.send(5)
مقدار
5 را به Generator میفرستد و Generator به yield result میرسد.⚠️ نکته مهم
قبل از اولین
send() معمولاً باید Generator را با:next(generator)
تا اولین
yield جلو ببریم.این کار Generator را آماده دریافت مقدار میکند.
🧠 خلاصه
yield → تولید مقدار و توقف موقت
next() → ادامه Generator تا yield بعدی
send(value) → ارسال مقدار به yield
Generator فقط یک تولیدکننده ساده نیست؛ میتواند بین کد بیرونی و خودش داده رد و بدل کند.
🎯 تمرین
Generator زیر را کامل کن تا عدد دریافتشده را دو برابر کند:
def double():
# code
generator = double()
next(generator)
result = generator.send(7)
print(result)
خروجی مورد انتظار:
14
✅ پاسخ کامل تمرین
def double():
number = yield
result = number * 2
yield result
generator = double()
next(generator)
result = generator.send(7)
print(result)
خروجی:
14
در اینجا ابتدا:
next(generator)
Generator را تا اولین
yield جلو میبرد.سپس:
generator.send(7)
عدد
7 را به این قسمت میرساند:number = yield
بنابراین:
number = 7
7 * 2 = 14
و در نهایت:
yield result
مقدار
14 را تولید میکند.پست ۱۱۸ از دوره جامع Python 🐍