سطح مقدماتی (Beginner Level)
در پایتون، وقتی داخل یک کلاس (Class) تابعی تعریف میکنیم، معمولاً اولین پارامتر آن self است. اینها Instance Method نام دارند و به نمونهی ساخته شده از کلاس دسترسی دارند. اما گاهی نیاز داریم متدی داشته باشیم که به self نیاز نداشته باشد یا به جای نمونه، به خودِ کلاس دسترسی داشته باشد. برای این کار از Static Method و Class Method استفاده میکنیم.
۱. متدهای معمولی (Instance Methods)
این متدها رفتار پیشفرض در پایتون هستند. اولین پارامتر آنها self است که به آبجکت (Object) اشاره میکند.
۲. استاتیک متد (Static Method)
اگر متدی داخل کلاس باشد اما هیچ نیازی به اطلاعات آن کلاس یا نمونههای آن نداشته باشد، آن را با دکوریتور @staticmethod تعریف میکنیم. این متد مانند یک تابع معمولی است که فقط برای نظمدهی داخل کلاس قرار گرفته است. ورودی self یا cls ندارد.
# Example 2: Static Method syntax
class MathUtils:
@staticmethod
def add(a, b):
# No self, no cls needed
return a + b
۳. کلاس متد (Class Method)
این متدها به جای self، اولین پارامترشان cls است که به خود کلاس اشاره میکند (نه نمونه ساخته شده). این متدها معمولاً برای تغییر متغیرهای سطح کلاس یا ساخت نمونههای جدید (Alternative Constructors) استفاده میشوند. برای تعریف آنها از دکوریتور @classmethod استفاده میکنیم.
سطح پیشرفته (Professional Level)
در سطح حرفهای، انتخاب بین @staticmethod و @classmethod تاثیر زیادی بر معماری کد، قابلیت ارثبری (Inheritance) و الگوهای طراحی (Design Patterns) دارد.
الگوی Factory با استفاده از Class Method
یکی از مهمترین کاربردهای classmethod، ساخت Alternative Constructors است. فرض کنید میخواهید آبجکت خود را علاوه بر ورودیهای معمولی، از طریق یک فایل یا یک رشته متنی خاص نیز بسازید.
تفاوت در ارثبری (Inheritance Behavior)
تفاوت کلیدی اینجاست: وقتی کلاسی را ارثبری میکنید، classmethod با کلاس فرزند (Child Class) سازگار میشود (یعنی cls به کلاس فرزند اشاره میکند)، اما staticmethod هیچ اطلاعی از کلاس فراخوانیکننده ندارد.
چه زمانی از کدام استفاده کنیم؟
۱. از @staticmethod استفاده کنید اگر:
* تابع شما منطقاً به کلاس مربوط است اما هیچ تعاملی با self (اینستنس) یا cls (کلاس) ندارد.
* یک تابع Utility خالص است (مثل تبدیل واحد، اعتبارسنجی داده ورودی).
* میخواهید کد را ایزوله کنید تا مطمئن شوید وضعیت کلاس را تغییر نمیدهد.
۲. از @classmethod استفاده کنید اگر:
* نیاز دارید یک نمونه (Instance) از کلاس بسازید (Factory Methods).
* نیاز به دسترسی یا تغییر متغیرهای سطح کلاس (Class Attributes) دارید.
* میخواهید متد شما در زمان ارثبری، با کلاس فرزند سازگار باشد (cls به درستی به Subclass اشاره کند).
# Advanced Example 3: Abstract structure for validation
class DataProcessor:
@staticmethod
def is_valid(data):
# مستقل از کلاس، فقط چک میکند داده معتبر است یا خیر
return data is not None and len(data) > 0
@classmethod
def process(cls, data):
if cls.is_valid(data):
return f"{cls.__name__} processed {data}"
return "Invalid Data"