Какова предпочтительная техника для преобразования свойств объекта в отсортированный список кортежей? - PullRequest
1 голос
/ 29 ноября 2009

Я работаю с библиотекой с открытым исходным кодом, и они определяют класс следующим образом:

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?

Просто ищу некоторые мнения и другие приемы, которые могут быть лучше для этого.

Ответы [ 2 ]

6 голосов
/ 29 ноября 2009

Если вы ищете переменные класса целочисленного типа, вы можете сделать это следующим образом:

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

Проверьте модуль inspect для получения дополнительной информации.


В качестве отступления: вы можете использовать PROVIDER_CHOICES.sort(key=...) в последней строке, которая выполняет сортировку по месту.

Редактировать: getmembers возвращает отсортированный список, как указано в документации, поэтому sorted не требуется (спасибо Дж. Ф. Себастьян)

0 голосов
/ 29 ноября 2009

Если вы беспокоитесь о методах и других типах атрибутов, просто отфильтруйте их тоже.

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

Вы просто должны выполнить это один раз для каждого рассматриваемого класса, поэтому скорость не должна быть проблемой для начала. Если вас это действительно волнует, вы можете просто сохранить список в самом классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...