简体   繁体   English

元类 - 不能取代类字典

[英]Metaclass - cannot replace class dict

Running this (Python 3.3.1): 运行它(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())

i am getting: 我正进入(状态:

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__')])

The class attributes are not sorted by their definition order. 类属性不按其定义顺序排序。

What am i doing wrong to use OrderedDict as class __dict__ ? 使用OrderedDict作为类__dict__我做错了什么?

The __prepare__ method in a mataclass allows you to provide your own custom object in place of the dict used for class initialisation. mataclass中的__prepare__方法允许您提供自己的自定义对象来代替用于类初始化的dict However you cannot change the type of object actually used by the class, that will be an instance of an internal type known as mappingproxy and is unordered. 但是,您无法更改类实际使用的对象类型,这将是一个称为mappingproxy的内部类型的实例,并且是无序的。 If you want to preserve the order in which the attributes where defined you must store that separately: 如果要保留定义的属性必须单独存储的顺序:

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']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM