元类 - 不能取代类字典

war*_*iuc 3 python metaclass python-3.x

运行它(Python 3.3.1):

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())
Run Code Online (Sandbox Code Playgroud)

我正进入(状态:

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__')])
Run Code Online (Sandbox Code Playgroud)

类属性不按其定义顺序排序.

OrderedDict作为班级使用我做错了__dict__什么?

Dun*_*can 6

__prepare__在mataclass方法使您可以提供自己的自定义对象来代替的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']
Run Code Online (Sandbox Code Playgroud)