Ответ 1
Хорошо, вы бросили в смесь немало концепций! Я собираюсь вытащить несколько конкретных вопросов, которые у вас есть.
В общем, понимание супер, MRO и metclasses сделано намного сложнее, потому что в этой сложной области было много изменений в последних версиях Python.
Собственная документация Python является очень хорошей ссылкой и полностью обновлена. Существует статья статья IBM developerWorks, которая прекрасно подходит для внедрения и использует более учебный подход, но обратите внимание, что ей пять лет, и много тратит много времени на подходы к метаклассам в старом стиле.
super
- это доступ к суперклассам объекта. Это сложнее, чем (например) ключевое слово Java super
, в основном из-за множественного наследования в Python. Поскольку Super Considered Harmful" объясняет, использование super()
может привести к тому, что вы неявно используете цепочку суперклассов, порядок которой определяется Порядок разрешения метода (MRO).
Вы можете легко просмотреть MRO для класса, вызвав mro()
в классе (а не в экземпляре). Обратите внимание, что метаклассы не находятся в иерархии суперклассов объекта.
Thomas 'описание метаклассов здесь превосходно:
Метакласс является классом класса. Как класс определяет, как экземпляр класса ведет себя, метакласса определяет поведение класса. Класс является экземпляром метакласса.
В примерах, которые вы приводите, вот что происходит:
-
Вызов
__new__
пузырялся до следующего MRO. В этом случаеsuper(MyType, cls)
будет разрешеноtype
; вызовtype.__new__
позволяет Python завершите нормальный экземпляр шаги создания. -
В этом примере используются метаклассы для обеспечения синглотона. Он переопределение
__call__
в метакласса, чтобы всякий раз, когда класс экземпляр создается, он перехватывает это, и может обойти экземпляр создание, если уже есть (хранится вcls.instance
). Заметка что переопределение__new__
в метакласс не будет достаточно хорош, потому что это называется только когда создавая класс. Переопределение__new__
в классе будет работать, однако. -
Это показывает путь к динамическому создать класс. Вот он добавление имени класса к имени созданного класса и добавление его в иерархию классов тоже.
Я не совсем уверен, какой пример кода вы ищете, но здесь краткий, показывающий метаклассы, наследование и разрешение метода:
class MyMeta(type):
def __new__(cls, name, bases, dct):
print "meta: creating %s %s" % (name, bases)
return type.__new__(cls, name, bases, dct)
def meta_meth(cls):
print "MyMeta.meta_meth"
__repr__ = lambda c: c.__name__
class A(object):
__metaclass__ = MyMeta
def __init__(self):
super(A, self).__init__()
print "A init"
def meth(self):
print "A.meth"
class B(object):
__metaclass__ = MyMeta
def __init__(self):
super(B, self).__init__()
print "B init"
def meth(self):
print "B.meth"
class C(A, B):
__metaclass__ = MyMeta
def __init__(self):
super(C, self).__init__()
print "C init"
>>> c_obj = C()
meta: creating A (<type 'object'>,)
meta: creating B (<type 'object'>,)
meta: creating C (A, B)
B init
A init
C init
>>> c_obj.meth()
A.meth
>>> C.meta_meth()
MyMeta.meta_meth
>>> c_obj.meta_meth()
Traceback (most recent call last):
File "mro.py", line 38, in <module>
c_obj.meta_meth()
AttributeError: 'C' object has no attribute 'meta_meth'