2013-05-20 2 views
3

Запуск этого (Python 3.3.1):метаклассов - не может заменить класс Dict

from collections import OrderedDict 


class MyType(type): 
    @classmethod 
    def __prepare__(*args): 
     return OrderedDict() 


class MyClass2(metaclass=MyType): 

    attr1 = 1 
    attr2 = 2 
    attr3 = 3 
    attr4 = 4 
    attr5 = 5 

    def __init__(self): 
     self.attr6 = 6 

    def func(self): 
     pass 



print(MyClass2.__dict__.items()) 

я получаю:

dict_items([('__weakref__', <attribute '__weakref__' of 'MyClass2' objects>), ('__dict__', <attribute '__dict__' of 'MyClass2' objects>), ('__init__', <function MyClass2.__init__ at 0x7f08a106dc20>), ('__doc__', None), ('attr4', 4), ('attr5', 5), ('attr2', 2), ('attr3', 3), ('attr1', 1), ('func', <function MyClass2.func at 0x7f089f995c20>), ('__module__', '__main__')]) 

Атрибуты класса не сортируются по их порядку определения.

Что я делаю неправильно использовать OrderedDict как класс __dict__?

ответ

6

Метод __prepare__ в матакласе позволяет вам предоставить свой собственный пользовательский объект вместо dict, используемого для инициализации класса. Однако вы не можете изменить тип объекта, фактически используемый классом, который будет экземпляром внутреннего типа, который известен как mappingproxy и неупорядочен. Если вы хотите сохранить порядок, в котором атрибуты, в которых они определены, вы должны хранить это отдельно:

class OrderedClass(type): 
     @classmethod 
     def __prepare__(metacls, name, bases): 
      return OrderedDict() 

     def __new__(cls, name, bases, classdict): 
      result = type.__new__(cls, name, bases, classdict) 
      result.member_names = list(classdict.keys()) 
      return result 


class MyClass2(metaclass=OrderedClass): 

    attr1 = 1 
    attr2 = 2 
    attr3 = 3 
    attr4 = 4 
    attr5 = 5 

    def __init__(self): 
     self.attr6 = 6 

    def func(self): 
     pass 

>>> MyClass2.member_names 
['__module__', '__qualname__', 'attr1', 'attr2', 'attr3', 'attr4', 'attr5', '__init__', 'func'] 
+1

Hm, неожиданно ... – warvariuc

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

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