我正在使用一个开源库,他们定义了一个类似的类:
class Provider(object):
""" Defines for each of the supported providers """
DUMMY = 0
EC2 = 1
EC2_EU = 2
RACKSPACE = 3
SLICEHOST = 4
GOGRID = 5
VPSNET = 6
LINODE = 7
VCLOUD = 8
RIMUHOSTING = 9
我需要获取属性(DUMMY,EC2等)并将它们转换为元组的排序列表,如下所示:
[(0, 'DUMMY'), (1, 'EC2'), ...]
我想对属性本身的名称进行排序。我想出了一些解决这个问题的方法,其中包括以下几种处理这种方法的低效方法:
import operator
from libcloud.types import Provider
PROVIDER_CHOICES = [(v,k) for k, v in vars(Provider).items()
if not k.startswith('__')]
PROVIDER_CHOICES = sorted(PROVIDER_CHOICES, key=operator.itemgetter(1))
它有效但似乎不优雅,并且可能有更好的方法。通过执行if not k.startswith('__')
我也看到了构建列表的方式中的缺陷 - 主要是如果开源库将方法添加到Provider类的话?
只是寻找一些可能更有效的意见和其他技术。
答案 0 :(得分:6)
如果要查找类型为integer的类变量,可以这样做:
import inspect
PROVIDER_CHOICES = inspect.getmembers(Foo, lambda x: isinstance(x, int))
查看inspect模块以获取更多信息。
顺便说一句:您可以在最后一行使用PROVIDER_CHOICES.sort(key=...)
,这是一个就地排序。
编辑:getmembers
返回文档中所述的排序列表,因此不需要sorted
(感谢J.F. Sebastian)
答案 1 :(得分:0)
如果您担心方法和其他类型的属性,也可以过滤它们。
PROVIDER_CHOICES = [(v,k) for k, v in vars(Provider).iteritems()
if not k.startswith('_') and isinstance(v,int)]
PROVIDER_CHOICES.sort( key=itemgetter(1) )
你必须为每个有问题的课程运行一次,所以速度不应该是一个问题。如果您真的关心,您可以将列表存储在类本身上。