3

运行这个(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())

我正进入(状态:

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__什么?

4

1 回答 1

6

mataclass 中的__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']
于 2013-05-20T11:12:54.577 回答