سؤال

ولقد تم في محاولة لمعرفة المزيد عن metaclasses في بيثون. أحصل على الفكرة الرئيسية، ولكن أنا لا يمكن أن يبدو لتفعيل آلية. كما أفهمها، يمكنك تحديد M لتكون على metaclass عند بناء K الفئة عن طريق وضع __metaclass__ إلى M على المستوى العالمي أو فئة. لاختبار هذا الخروج، كتبت البرنامج التالي:

p = print

class M(type):
    def __init__(*args):
        type.__init__(*args)
        print("The rain in Spain")

p(1)
class ClassMeta:
    __metaclass__ = M

p(2)
__metaclass__ = M
class GlobalMeta: pass

p(3)
M('NotMeta2', (), {})

p(4)

ولكن، عندما كنت تشغيله، وأحصل على الإخراج التالية:

C:\Documents and Settings\Daniel Wong\Desktop>python --version
Python 3.0.1

C:\Documents and Settings\Daniel Wong\Desktop>python meta.py
1
2
3
The rain in Spain
4

ويجب أن لا أرى "المطر في اسبانيا" بعد 1 و 2؟ ما الذي يحدث هنا؟

هل كانت مفيدة؟

المحلول

في بيثون 3 (الذي تستخدمه) يتم تحديد metaclasses التي كتبها معلمة الكلمة الرئيسية في تعريف الفئة:

class ClassMeta(metaclass=M):
  pass

وتحديد ملكية من الدرجة __metaclass__ أو المتغير العالمي في بناء الجملة القديمة من بيثون 2.x و لا تعد معتمدة. انظر أيضا "ما هو الجديد في بيثون 3" و <ل أ href = "http://www.python.org/dev/peps/pep-3115/" يختلط = "نوفولو noreferrer"> PEP 2115 .

نصائح أخرى

وهذا يعمل كما هو متوقع في بيثون 2.6 (وأقدم)، ولكن في 3.0 المحددة metaclasses مختلف:

class ArgMeta(metaclass=M): ...

وبناء جملة metaclasses ديه تغير في بايثون 3.0. السمة __metaclass__ لم يعد الخاصة إما في الدرجة ولا مستوى الوحدة النمطية. أن تفعل ما نحاول القيام به، تحتاج إلى تحديد metaclass كحجة رئيسية للبيان class:

p = print

class M(type):
    def __init__(*args):
        type.__init__(*args)
        print("The rain in Spain")

p(1)
class ClassMeta(metaclass=M): pass

والعائد:

1
The rain in Spain

وكما كنت تتوقع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top