الميتاكلاسات (Metaclasses) في Python هي فئات خاصة تقوم بإنشاء وإدارة الفئات الأخرى. بما أن كل شيء في Python هو كائن، بما في ذلك الفئات، يمكن اعتبار الميتاكلاسات على أنها "فئات للفئات". فهي توفر آلية للتحكم في عملية إنشاء الفئات وتعديل سلوكها في مرحلة التعريف.
كيفية عمل الميتاكلاسات
عندما يواجه Python تعريف فئة، فإنه يستخدم تلقائيًا الميتاكلاس type لإنشاء هذه الفئة. تبدو العملية كالتالي:
class MyClass:
pass
داخليًا، ينفذ Python الأمر التالي:
MyClass = type('MyClass', (), {})
حيث:
'MyClass'— اسم الفئة()— مجموعة (tuple) الفئات الأم{}— قاموس الخصائص والطرق (attributes and methods) للفئة
الميتاكلاس المدمج type هو المسؤول عن إنشاء جميع الفئات في Python بشكل افتراضي.
إنشاء ميتاكلاس خاص بك
يتم إنشاء الميتاكلاسات المخصصة عن طريق الوراثة من type وإعادة تعريف طرقه:
class MyMeta(type):
def __new__(cls, name, bases, attrs):
print(f"جارٍ إنشاء الفئة {name}")
attrs['created_by_metaclass'] = True
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=MyMeta):
pass
print(MyClass.created_by_metaclass) # True
الطرق الأساسية للميتاكلاسات
__new__
يتحكم في إنشاء الفئة. يتم استدعاؤه قبل __init__ ويعيد الفئة الجديدة:
class CreationMeta(type):
def __new__(cls, name, bases, attrs):
# تعديل الخصائص قبل إنشاء الفئة
attrs['class_id'] = id(cls)
return super().__new__(cls, name, bases, attrs)
__init__
يقوم بتهيئة الفئة التي تم إنشاؤها بالفعل:
class InitMeta(type):
def __init__(cls, name, bases, attrs):
print(f"تهيئة الفئة {name}")
super().__init__(name, bases, attrs)
__call__
يحدد السلوك عند إنشاء نسخ (instances) من الفئة:
class CallMeta(type):
def __call__(cls, *args, **kwargs):
print(f"إنشاء نسخة من {cls.__name__}")
return super().__call__(*args, **kwargs)
أمثلة عملية للتطبيق
تحويل الخصائص تلقائيًا إلى أحرف كبيرة
class UpperAttrMeta(type):
def __new__(cls, name, bases, attrs):
uppercase_attrs = {}
for attr_name, attr_value in attrs.items():
if not attr_name.startswith('__'):
uppercase_attrs[attr_name.upper()] = attr_value
else:
uppercase_attrs[attr_name] = attr_value
return super().__new__(cls, name, bases, uppercase_attrs)
class MyClass(metaclass=UpperAttrMeta):
attr1 = 'value1'
attr2 = 'value2'
print(hasattr(MyClass, 'ATTR1')) # True
print(hasattr(MyClass, 'attr1')) # False
تطبيق نمط Singleton
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class DatabaseConnection(metaclass=SingletonMeta):
def __init__(self):
print("إنشاء اتصال بقاعدة البيانات")
db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(db1 is db2) # True
التحقق من صحة بنية الفئات
class ValidatedMeta(type):
def __new__(cls, name, bases, attrs):
# التحقق من وجود طريقة إلزامية
if 'process' not in attrs:
raise TypeError(f"الفئة {name} يجب أن تحتوي على طريقة 'process'")
return super().__new__(cls, name, bases, attrs)
class MyService(metaclass=ValidatedMeta):
def process(self):
pass # هذا سيعمل بنجاح