کاربرد متاکلاس در پایتون چیست؟
متاکلاسها در پایتون، مفهومی عمیق و کلیدی در طراحی و ساختار کلاسها هستند. به عبارت ساده، متاکلاس، "کلاس کلاسها" است. به این معنا که یک متاکلاس، نحوه رفتار یک کلاس را تعریف میکند، در حالی که خود کلاسها نحوه رفتار اشیای ایجاد شده از آنها را تعیین میکنند.
مفهوم متاکلاس
در پایتون، همه چیز به عنوان یک شی در نظر گرفته میشود. وقتی شما یک کلاس تعریف میکنید، در واقع یک شی از نوع متاکلاس ایجاد میکنید. یعنی هر بار که یک کلاس جدید با استفاده از عبارت class
تعریف میشود، در واقع متاکلاس type
صدا زده میشود تا آن کلاس را ایجاد کند.
متاکلاسها معمولاً برای انجام کارهای خاصی در زمان ایجاد کلاسها استفاده میشوند. برای مثال، با استفاده از متاکلاس، میتوان رفتار کلاس را در زمان ایجادش تغییر داد، مانند ثبت کلاسهای جدید در یک فهرست خاص یا تغییر نام ویژگیهای کلاس.
نحوه کار متاکلاسها
متاکلاسها میتوانند به شکل یک کلاس که از type
ارث بری میکند، تعریف شوند. برای مثال:
class MyMeta(type):
def __new__(cls, name, bases, attrs):
# تغییرات دلخواه بر روی کلاس
return super(MyMeta, cls).__new__(cls, name, bases, attrs)
class MyClass(metaclass=MyMeta):
pass
در این مثال، MyMeta
به عنوان متاکلاس برای MyClass
تعریف شده است. در متد __new__
، شما میتوانید به ویژگیها و رفتارهای کلاس دسترسی پیدا کنید و آنها را تغییر دهید.
کاربردهای متاکلاس
متاکلاسها معمولاً در شرایط خاصی کاربرد دارند، مثلاً:
- تعریف APIهای پیچیده: مانند ORM در فریمورک Django، که متاکلاسها به شما اجازه میدهند تا از کلاسهای ساده، کلاسهایی بسازید که وابستگیهای پیچیدهتری به پایگاه دادهها دارند.
- بهبود ساختار و نامگذاری خودکار: شما میتوانید با استفاده از متاکلاس، نام ویژگیها یا متدهای کلاس را تغییر دهید، مانند تبدیل تمام نامهای ویژگیها به حروف بزرگ.
- انجام بررسیها و اعتبارسنجیهای خاص: میتوانید چک کنید که آیا یک کلاس جدید، ویژگیهای خاصی را دارد یا خیر، و بر اساس آن عمل کنید.
class UpperAttrMetaclass(type):
def __new__(cls, clsname, bases, attrs):
uppercase_attrs = {
attr.upper(): value for attr, value in attrs.items()
}
return super().__new__(cls, clsname, bases, uppercase_attrs)
class MyClass(metaclass=UpperAttrMetaclass):
bar = 'baz'
print(hasattr(MyClass, 'bar')) # False
print(hasattr(MyClass, 'BAR')) # True