2015-11-02 7 views
1

У меня есть метаклассом как этотПочему класс имеет атрибуты своего метакласса?

class UpperMeta(type): 
    def __new__(cls, clsname, bases, dct): 
     uppercase_attr = {} 
     for name, val in dct.items(): 
      if not name.startswith('__'): 
       uppercase_attr[name.upper()] = val 
      else: 
       uppercase_attr[name] = val 

     return super(UpperMeta, cls).__new__(cls, clsname, bases, uppercase_attr) 

    def echo(cls): 
     return 'echo' 

class B(object): 
    __metaclass__ = UpperMeta 

assert hasattr(B, 'echo') 
assert B.echo() == 'echo' 
assert not issubclass(B, UpperMeta) 

Мой вопрос:

  1. Почему класс B есть echo -метода? Если B не является подклассом UpperMeta, у него не должно быть echo attr?
  2. Какие атрибуты получают класс из метакласса?

ответ

1

class объект B имеет typeUpperMeta.

Это приводит к тому, что все классные методы UpperMeta доступны для класса B. Атрибут не на классе B, но получает проксированном из класса B «S (B класс, не экземпляр B)

>>> print dir(B) 
# General lack of echo() 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] 

Это здесь:

>>> print dir(B.__class__) 
['__abstractmethods__', '__base__', ..., 'echo', 'mro'] 

От documentation:

Поведение по умолчанию для доступа к атрибутам - это получение, установка или удаление атрибута f rom словарь объекта. Например, a.x имеет цепочку поиска , начиная с. dict ['x'], затем тип (a). dict ['x'] и продолжения базовых классов типа (a), исключая метаклассы.


Это немного сбивает с толку в конце «... исключая метаклассами ..», что на самом деле означает метаклассами типа (а), поэтому говорят, что если ваш метаклассом UpperMeta имеет метакласса TopMeta и TopMeta определяет sos(), что один не будет искаться:

class TopMeta(type): 
    def __new__(cls, clsname, bases, dct): 
     uppercase_attr = {} 
     for name, val in dct.items(): 
      if not name.startswith('__'): 
       uppercase_attr[name.upper()] = val 
      else: 
       uppercase_attr[name] = val 

     return super(TopMeta, cls).__new__(cls, clsname, bases, uppercase_attr) 

    def sos(cls): 
     return 'sos' 

class UpperMeta(type): 
    __metaclass__ = TopMeta 
    def __new__(cls, clsname, bases, dct): 
     uppercase_attr = {} 
     for name, val in dct.items(): 
      if not name.startswith('__'): 
       uppercase_attr[name.upper()] = val 
      else: 
       uppercase_attr[name] = val 

     return super(UpperMeta, cls).__new__(cls, clsname, bases, uppercase_attr) 

class B(object): 
    __metaclass__ = UpperMeta 

assert not hasattr(B, 'sos') 

только говорить, что когда-нибудь объяснил метаклассами правильно: David Beazley - Python 3 Metaprogramming. У вас есть только первые 80 минут или около того.

1

Почему класс B имеет метод эха, B не является подклассом UpperMeta, он не должен иметь echo attr?

Если посмотреть на What is a metaclass in Python? или Customizing class creation, вы видите, что (цитаты из питона Документов)

если __metaclass__ определяется то вызываемым возложенные на него будет названием вместо типа().

type()

, по существу, динамическая форма класса заявления. Имя строки является именем класса и становится атрибутом __name__; основы кортеж перечисляет базовые классы и становится атрибутом __bases__; и словарь dict - это пространство имен, содержащее определения для тела класса и становится атрибутом __dict__. Например, следующие два оператора создания идентичных объектов типа:

>>> class X(object): 
...  a = 1 
... 
>>> X = type('X', (object,), dict(a=1)) 

Это, это «так же, как» расширение класса. Это также отвечает

Какой класс атрибута получить из метакласса?

Практически все.

Пожалуйста, be aware that

Если вам интересно, нужно ли вам их, вы не (люди, которые на самом деле нужно им знать с уверенностью, что они нуждаются в них, и не нужны объяснения о Зачем).

еще в video posted by @Sebastian, он говорит

Q: Вы можете быть слишком много [метапрограммированием] A: Нет

Таким образом, он не думает, что это достаточно важно, чтобы учиться.

+0

Я не мог найти цитату! Благодарю. –

+0

@ Себастьян: Добро пожаловать. Это сразу после начала. Спасибо тебе за видео. –

 Смежные вопросы

  • Нет связанных вопросов^_^