在python中订购枚举值 [英] Ordering enum value in python

查看:90
本文介绍了在python中订购枚举值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要安排枚举的顺序。有人建议如何解决这个问题?以下枚举元类正在使用:





pre>类型):
def __new __(typ,name,bases,attrs):
cls_attrs = {}
cls_choices = []
for attr_name,attrs.items()中的值:
cls_attrs [attr_name] = attr_name.lower()
如果不是attr_name.startswith(__):
cls_choices.append((attr_name.lower(),value))

def choice(cls):
return cls_choices

def values(cls,value = None):
如果值为None:
return {选择[0]:unicode(选择[1])在cls.choices()中的选择}
elif isinstance(value,list):
return {choice [0]:unicode(choice [1] )选择cls.choices()如果选择[0]在值}
else:
返回unicode(dict(cls.choices())。get(value))

def键(cls,nil = False):
它ems = [item [0] for clschoices()]
if nil:
items.append('')

返回项目

def combined_length(cls):
return len(,。join(cls.values()。keys()))

def max_length(cls):
return max(map(len,cls.values()。keys()))

cls_attrs ['choices'] = classmethod(choices)
cls_attrs ['values'] = classmethod值)
cls_attrs ['keys'] = classmethod(keys)
cls_attrs ['combined_length'] = classmethod(combine_length)
cls_attrs ['max_length'] = classmethod(max_length)

返回类型(名称,基数,cls_attrs)

枚举的一个例子是如下:

  class SideHemType:
__ordering__ = ['double','single']
__metaclass__ = EnumMeta

Single =不透明面料单面下摆
Double =透明面料双面边框


class TestEnumOrdering:
print SideHemType.keys()
print SideHemType.values()

通过打印Enum SideHemType,首先打印Double,然后单击。但我想要先单,然后双。

解决方案

您的枚举在3个地方失去了排序。首先,类体上的属性存储在字典中,然后将项目复制到另一个字典中。最后,你的 values()返回第3个字典。字典不保存排序,并且不可能在类体内获取属性的排序。



使用此系统最简单的方法是使变量



  __ ordering__ = ['single','double'] 

并使 values()返回一个元组列表(如 dict.items()

  class EnumMeta(type):
def __new __(typ,name, ,attrs):
cls_attrs = {}
cls_choices = {}
$ b对于attr_name,attrs.items()中的值:
cls_attrs [attr_name] = attr_name。 lower()
如果不是attr_name.startswith(__):
cls_choices [attr_name.lower()] = value

ordering = attrs.get('__ ordering__')
如果订购==无:
订购=排序(cls_choices.keys())

定义选择(cls):
返回dict(cls_choices)

def值(cls,value = None):
如果值为None:
返回[(k,cls_choices [k])for k在排序]
elif not isinstance(value,basestring):
return [(k,cls_choices [k])for k in value]
else:
return unicode(cls_choices.get(value))

def key(cls,nil = False):
items = list(ordering)
如果nil:
items.append('')

返回项目

def combined_length(cls):
return len(,。join(cls.values()。keys()))

def max_length (cls):
return max(map(len,cls.values()。keys()))

cls_attrs ['choices'] = classmethod(choices)
cls_attrs ['values'] = classmethod(values)
cls_attrs ['keys'] = classmethod(keys)
cls_attrs ['combined_length'] = classmethod _length)
cls_attrs ['max_length'] = classmethod(max_length)

返回类型(name,bases,cls_attrs)

class SideHemType:
__ordering__ = ['double','single']
__metaclass__ = EnumMeta

Single =不透明面料的单面下摆
Double =透明面料的双面下摆


打印SideHemType.keys()
打印SideHemType.values()


I would like to be able to arrange the ordering of Enum. Has somebody suggestions how this can be solved?

The following Enum meta class is using:

class EnumMeta(type):
    def __new__(typ, name, bases, attrs):
        cls_attrs = {}
        cls_choices = []
        for attr_name, value in attrs.items():
            cls_attrs[attr_name] = attr_name.lower()
            if not attr_name.startswith("__"):
                cls_choices.append((attr_name.lower(), value))

        def choices(cls):
            return cls_choices

        def values(cls, value=None):
            if value is None:
                return {choice[0]: unicode(choice[1]) for choice in cls.choices()}
            elif isinstance(value, list):
                return {choice[0]: unicode(choice[1]) for choice in cls.choices() if choice[0] in value}
            else:
                return unicode(dict(cls.choices()).get(value))

        def keys(cls, nil=False):
            items = [item[0] for item in cls.choices()]
            if nil:
                items.append('')

            return items

        def combined_length(cls):
            return len(",".join(cls.values().keys()))

        def max_length(cls):
            return max(map(len, cls.values().keys()))

        cls_attrs['choices'] = classmethod(choices)
        cls_attrs['values'] = classmethod(values)
        cls_attrs['keys'] = classmethod(keys)
        cls_attrs['combined_length'] = classmethod(combined_length)
        cls_attrs['max_length'] = classmethod(max_length)

        return type(name, bases, cls_attrs)

An example of an Enum is as follow:

class SideHemType:
    __ordering__ = ['double', 'single']
    __metaclass__ = EnumMeta

    Single = "Single side hem for opaque fabrics"
    Double = "Double side hem for transparent fabrics"


  class TestEnumOrdering:
        print SideHemType.keys()
        print SideHemType.values() 

By printing the Enum SideHemType first Double is printed and then Single. But I would like first Single and then Double.

解决方案

Your Enum loses the ordering in 3 places. First the attributes on the class body are stored in a dictionary, then you copy the items into another dictionary. Finally your values() returns a 3rd dictionary. A dictionary does not save ordering, and it is impossible to get the ordering of the attributes within the class body.

With this system the easiest is to have a variable

__ordering__ = [ 'single', 'double' ]

And make the values() return a list of tuples (like dict.items()).

class EnumMeta(type):
    def __new__(typ, name, bases, attrs):
        cls_attrs = {}
        cls_choices = {}

        for attr_name, value in attrs.items():
            cls_attrs[attr_name] = attr_name.lower()
            if not attr_name.startswith("__"):
                cls_choices[attr_name.lower()] = value

        ordering = attrs.get('__ordering__')
        if ordering == None:
            ordering = sorted(cls_choices.keys())

        def choices(cls):
            return dict(cls_choices)

        def values(cls, value=None):
            if value is None:
                return [ (k, cls_choices[k] ) for k in ordering ]
            elif not isinstance(value, basestring):
                return [ (k, cls_choices[k] ) for k in value ]
            else:
                return unicode(cls_choices.get(value))

        def keys(cls, nil=False):
            items = list(ordering)
            if nil:
                items.append('')

            return items

        def combined_length(cls):
            return len(",".join(cls.values().keys()))

        def max_length(cls):
            return max(map(len, cls.values().keys()))

        cls_attrs['choices'] = classmethod(choices)
        cls_attrs['values'] = classmethod(values)
        cls_attrs['keys'] = classmethod(keys)
        cls_attrs['combined_length'] = classmethod(combined_length)
        cls_attrs['max_length'] = classmethod(max_length)

        return type(name, bases, cls_attrs)

class SideHemType:
    __ordering__ = ['double', 'single']
    __metaclass__ = EnumMeta

    Single = "Single side hem for opaque fabrics"
    Double = "Double side hem for transparent fabrics"


print SideHemType.keys()
print SideHemType.values()

这篇关于在python中订购枚举值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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