Многоуровневые искусственные перечисления Python с использованием диапазона - PullRequest
11 голосов
/ 22 декабря 2010

Я пытаюсь создать класс перечислимого типа в Python, но он становится слишком длинным, когда вам нужно сделать

VARIABLE1, VARIABLE2, VARIABLE3, VARIABLE3, VARIABLE4, VARIABLE5, VARIABLE6, VARIABLE7, VARIABLE8, ... , VARIABLE14 = range(14)

и я попытался настроить его следующим образом, но в итоге не работал.

VARIABLE1,
VARIABLE2,
VARIABLE3,
...
VARIABLE14 = range(14)

Как бы я достиг этого самым простым способом?

Ответы [ 8 ]

8 голосов
/ 22 декабря 2010

Ого, я просто добавил скобки вокруг переменных, и это сработало

(VARIABLE1,
VARIABLE2,
VARIABLE3,
...
VARIABLE14) = range(14)
2 голосов
/ 16 марта 2016

Реализация enum похожа на namedtuple с использованием namedtuple. Эта enum функция создает класс с namedtuple и создает экземпляр класса с предоставленными аргументами. Аргументы - это строки tuple или list. Форма аргументов tuple или list используется для предоставления значения константам, таким образом сбрасывая последовательность значений. По умолчанию константы оцениваются, начиная с нуля.

def enum(name, *args):
    from collections import namedtuple

    kwargs = {}
    start = 0
    for arg in args:
        if isinstance(arg, basestring):
            kwargs[arg] = start
            start += 1
        elif isinstance(arg, (tuple, list)):
            if len(arg) != 2:
                raise ValueError('"{}" must be a two element tuple or list'.format(arg))
            attr, start = arg
            if isinstance(attr, basestring):
                if isinstance(start, int):
                    kwargs[attr] = start
                    start += 1
                else:
                    raise TypeError('second element of "{}" must be of type "int"'.format(arg))
            else:
                raise TypeError('first element of "{}" must be sub type of "basestring"'.format(arg))
        else:
            raise TypeError('Argument "{}" must be either sub type of "basestring", "tuple" or "list" of ("basestring", "int")'.format(arg))

    if isinstance(name, basestring):
        return namedtuple(name, kwargs.keys())(**kwargs)
    raise TypeError('Argument "{}" must be an instance of "basestring"'.format(name))

Usage;

In [663]: Color = enum('Color', 'black', 'white', 'red')

In [664]: Color.black
Out[664]: 0

In [665]: Color.red
Out[665]: 2

In [666]: #To start from 1

In [667]: Color = enum('Color', ('black',1), 'white', 'red')

In [668]: Color.black
Out[668]: 1

In [669]: Color.red
Out[669]: 3

In [670]: Animal = enum('Animal','cat', 'dog', ['lion',10],'tiger')

In [671]: Animal.dog
Out[671]: 1

In [672]: Animal.tiger
Out[672]: 11

In [673]: Animal.tiger = 12
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-673-8823b3c2482c> in <module>()
----> 1 Animal.tiger = 12

AttributeError: can't set attribute
2 голосов
/ 13 марта 2016

Используя новую библиотеку aenum и Python 3, вы можете сделать:

from aenum import Enum

class SomeEnum(Enum, start=0):
    VARIABLE1
    VARIABLE2
    VARIABLE3
    VARIABLE4
    VARIABLE5
    VARIABLE6
    VARIABLE7
    VARIABLE8
    VARIABLE9
    VARIABLE10
    VARIABLE11
    VARIABLE12
    VARIABLE13
    VARIABLE14

и при использовании выглядит следующим образом:

>>> SomeEnum.VARIABLE7
<SomeEnum.VARIABLE7: 6>

Примечание: aenumнаписано автором enum34

2 голосов
/ 22 декабря 2010

Вместо того, чтобы вручную печатать VARIABLE1, VARIABLE2 ... вы можете сделать это:

>>> for x in range(1, 15):
        globals()['VARIABLE{0}'.format(x)] = x

Делает, что вы хотите, без лишних усилий, набрав VARIABLE1 ... VARIABLE 14.

1 голос
/ 19 марта 2016

Узнав немного о функции дальности, вы можете исправить это в кратчайшие сроки. Посетите - документация для более подробной информации. Мы видим, что 2 apis: Диапазон (стоп) диапазон (начало, остановка [, шаг])

Где он просто возвращает список чисел в этом конкретном диапазоне с шагом, по умолчанию равным 1.

Следовательно, вам просто нужно убедиться, что ваш код соответствует тому, что вы можете сделать, явно указав python, что они находятся в одной строке, что вы можете сделать, добавив символ '\' в конце каждой строки. Также, если вы заключите их в '[]' или '()', отметив их как список кортежа, интерпретатор python будет неявно обрабатывать его как одну строку. Используйте перечисленные коды или поэкспериментируйте сами, чтобы освоиться.

1 голос
/ 18 марта 2016

Явным способом объединения строк является использование символов обратной косой черты:

VARIABLE1,\
VARIABLE2,\
VARIABLE3,\
...
VARIABLE14) = range(14)

и неявный способ заключить в скобки, квадратные или фигурные скобки:

[VARIABLE1,
 VARIABLE2,
 VARIABLE3,
 ...
 VARIABLE14] = range(14)
0 голосов
/ 19 марта 2016

Я часто нахожу словари более подходящими, чем перечисления, потому что они позволяют легко отображать целые числа более чем в одну переменную, функцию и т. Д. Например, присваивание in для функции и строки:

import numpy as np,

CC = [(np.sin, "Taking the sine"),
      (np.cos, "Taking the cosine"),
      (np.tan, "Taking the tangens")]
dCC = dict(enumerate(CC, start=1))  # built the enumerated dictionary


def calc(n, x):
    """ Perform operation on `x` defined by number `n` """
    f, s = dCC[n]  # map number to function and string
    y = f(x)
    print(s + " from %g results in %g" % (x, y))
    return y

y = calc(2, np.pi)  # prints: "Taking the tangens from 3.14159 results in -1"
0 голосов
/ 19 марта 2016

Создайте идентификаторы (переменные) в виде строк, таких как 'VARIABLE{}'.format(1), и создайте genexp, который yield s 2-элементный tuple s состоит из идентификатора и значения, такого как ('VARIABLE1', 0).

Этот ген может быть использован для подачи dict или dict.update. В случае ОП dict - это тот, который возвращается globals().

>>> globals().update(('VARIABLE{}'.format(x+1), x) for x in range(14))
>>> VARIABLE1
0
>>> VARIABLE14
13

Если присваиваемые значения не являются целыми числами enumerate может решить проблему именования переменных.

>>> globals().update(('VARIABLE{}'.format(i), x) for i, x in enumerate('abcdefghijklmn',1))
>>> VARIABLE1
'a'
>>> VARIABLE14
'n'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...