开发者

What is the preferred technique to convert an object's properties to a sorted list of tuples?

开发者 https://www.devze.com 2022-12-12 15:43 出处:网络
I\'m working with an open-source library and they define a class like so: class Provider(object): \"\"\" Defines for each of the supported providers \"\"\"

I'm working with an open-source library and they define a class like so:

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

I need to take the properties (DUMMY, EC2, etc.) and convert them to a sorted list of tuples that would look something like this:

[(0, 'DUMMY'), (1, 'EC2'), ...]

I want to sort on the name of the property itself. I've come up with a few ways to tackle this, including the following which seems like an inefficient way to handle this:

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))

It works but seems inelegant and like there may be a better way. I also see flaws in the way I'm constructing the list by doing the if not k.startswith('__') - mainly what if the open-source开发者_如何学C lib adds methods to the Provider class?

Just looking for some opinions and other techniques that may work better for this.


If you are looking for class variables that are of the type integer, you could do it like this:

import inspect
PROVIDER_CHOICES = inspect.getmembers(Foo, lambda x: isinstance(x, int))

Check out the inspect module for more information.


As an aside: you can use PROVIDER_CHOICES.sort(key=...) in your last line, which does an inplace sort.

Edit: getmembers returns a sorted list as stated in the documentation so sorted is unnecessary (thanks J.F. Sebastian)


If you worry about methods and other types of attributes just filter them out too.

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) )

You just have to run this once for every class in question, so speed shouldn't be a issue to begin with. If you really care, you can just store the list on the class itself.

0

精彩评论

暂无评论...
验证码 换一张
取 消