如何以与声明相同的顺序读取类属性? [英] How to read class attributes in the same order as declared?

查看:22
本文介绍了如何以与声明相同的顺序读取类属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个读取类属性并将它们存储在列表中的元类,但我希望列表 (cls.columns) 遵守声明顺序(即:mycol2, mycol3zutcoolmenfina 在我的例子中):

I am writing a metaclass that reads class attributes and store them in a list, but I want the list (cls.columns) to respect the declaration order (that is: mycol2, mycol3, zut, cool, menfin, a in my example):

import inspect
import pprint

class Column(object):
    pass

class ListingMeta(type):
    def __new__(meta, classname, bases, classDict):
        cls = type.__new__(meta, classname, bases, classDict)
        cls.columns = inspect.getmembers(cls, lambda o: isinstance(o, Column)) 
        cls.nb_columns = len(cls.columns)
        return cls

class Listing(object):
    __metaclass__ = ListingMeta
    mycol2 = Column()
    mycol3 = Column()
    zut = Column()
    cool = Column()
    menfin = Column()
    a = Column()

pprint.pprint(Listing.columns)

结果:

[('a', <__main__.Column object at 0xb7449d2c>),
 ('cool', <__main__.Column object at 0xb7449aac>),
 ('menfin', <__main__.Column object at 0xb7449a8c>),
 ('mycol2', <__main__.Column object at 0xb73a3b4c>),
 ('mycol3', <__main__.Column object at 0xb744914c>),
 ('zut', <__main__.Column object at 0xb74490cc>)]

这不遵守Listing 类的Column() 属性的声明顺序.如果我直接使用 classDict 也无济于事.

This does not respect the declaration order of Column() attributes for Listing class. If I use classDict directly, it does not help either.

我该如何继续?

推荐答案

在当前版本的 Python 中,类顺序被保留.有关详细信息,请参阅 PEP520.

In the current version of Python, the class ordering is preserved. See PEP520 for details.

在该语言的旧版本(3.5 及更低版本,但不是 2.x)中,您可以提供一个元类,该元类使用 OrderedDict 作为类命名空间.

In older versions of the language (3.5 and below, but not 2.x), you can provide a metaclass which uses an OrderedDict for the class namespace.

import collections 

class OrderedClassMembers(type):
    @classmethod
    def __prepare__(self, name, bases):
        return collections.OrderedDict()

    def __new__(self, name, bases, classdict):
        classdict['__ordered__'] = [key for key in classdict.keys()
                if key not in ('__module__', '__qualname__')]
        return type.__new__(self, name, bases, classdict)

class Something(metaclass=OrderedClassMembers):
    A_CONSTANT = 1

    def first(self):
        ...

    def second(self):
        ...

print(Something.__ordered__)
# ['A_CONSTANT', 'first', 'second']

这种方法不能帮助您处理现有的类,但是,您需要使用自省.

这篇关于如何以与声明相同的顺序读取类属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆