Как я должен лучше всего эмулировать и/или избежать перечисления в Python? [дубликат]

Вот еще один метод для итерации объекта.

   var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


Object.keys(p).forEach(key => { console.log(key, p[key]) })

5
задан Ned Batchelder 11 July 2010 в 20:49
поделиться

6 ответов

Существует большое хорошее обсуждение здесь.

3
ответ дан 18 December 2019 в 09:11
поделиться

Перечисления были предложены для включения на язык прежде, но были отклонены (см. http://www.python.org/dev/peps/pep-0354/), хотя существуют существующие пакеты, которые Вы могли использовать вместо того, чтобы писать Вашу собственную реализацию:

5
ответ дан 18 December 2019 в 09:11
поделиться

Наиболее распространенный перечислимый случай является перечисляемыми значениями, которые являются частью шаблона разработки Стратегии или состояния. Перечисления являются определенными состояниями или определенными дополнительными стратегиями, которые будут использоваться. В этом случае они - почти всегда неотъемлемая часть некоторого определения класса

class DoTheNeedful( object ):
    ONE_CHOICE = 1
    ANOTHER_CHOICE = 2 
    YET_ANOTHER = 99
    def __init__( self, aSelection ):
        assert aSelection in ( self.ONE_CHOICE, self.ANOTHER_CHOICE, self.YET_ANOTHER )
        self.selection= aSelection

Затем в клиенте этого класса.

dtn = DoTheNeeful( DoTheNeeful.ONE_CHOICE )
4
ответ дан 18 December 2019 в 09:11
поделиться

Что я вижу, чаще это, в контексте модуля верхнего уровня:

FOO_BAR = 'FOO_BAR'
FOO_BAZ = 'FOO_BAZ'
FOO_QUX = 'FOO_QUX'

... и позже...

if something is FOO_BAR: pass # do something here
elif something is FOO_BAZ: pass # do something else
elif something is FOO_QUX: pass # do something else
else: raise Exception('Invalid value for something')

Обратите внимание что использование is вместо == берет на себя риск здесь - он предполагает, что люди используют your_module.FOO_BAR вместо строки 'FOO_BAR' (который будет обычно интернироваться таким образом что is будет соответствовать, но на это, конечно, нельзя рассчитывать), и так может не быть соответствующим в зависимости от контекста.

Одно преимущество выполнения его, которым этот путь состоит в том, что путем взгляда где угодно ссылка на ту строку хранится, сразу очевидно, куда оно прибыло из; FOO_BAZ намного менее неоднозначно, чем 2.

Помимо этого, другой вещью, которая нарушает мое ре чувствительности Pythonic класс, который Вы предлагаете, является использование split(). Почему не только передают в кортеже, списке или другом счетном для запуска с?

3
ответ дан 18 December 2019 в 09:11
поделиться

Встроенный способ сделать перечисления:

(FOO, BAR, BAZ) = range(3)

который хорошо работает для маленьких наборов, но имеет некоторые недостатки:

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

Для полной перечислимой реализации в Python см.: http://code.activestate.com/recipes/67107/

2
ответ дан 18 December 2019 в 09:11
поделиться

Я запустил с чего-то, что много походит на ответ S.Lott, но я только перегрузил 'ул.' и 'eq' (вместо целого класса объекта), таким образом, я мог распечатать и сравнить значение перечисления.

class enumSeason():
    Spring = 0
    Summer = 1
    Fall = 2
    Winter = 3
    def __init__(self, Type):
        self.value = Type
    def __str__(self):
        if self.value == enumSeason.Spring:
            return 'Spring'
        if self.value == enumSeason.Summer:
            return 'Summer'
        if self.value == enumSeason.Fall:
            return 'Fall'
        if self.value == enumSeason.Winter:
            return 'Winter'
    def __eq__(self,y):
        return self.value==y.value

Печать (x) приведет к имени вместо значения, и два значения, содержащие Spring, будут равны друг другу.

   >>> x = enumSeason(enumSeason.Spring)
   >>> print(x)
   Spring
   >>> y = enumSeason(enumSeason.Spring)
   >>> x == y
   True
1
ответ дан 18 December 2019 в 09:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: