python २०१६ मैं पायथन में 'एनम' का प्रतिनिधित्व कैसे कर सकता हूं?




बिहार एएनएम नर्सिंग patna, bihar (24)

मैं मुख्य रूप से एक सी # डेवलपर हूं, लेकिन मैं वर्तमान में पायथन में एक परियोजना पर काम कर रहा हूं।

मैं पायथन में एनम के बराबर कैसे प्रतिनिधित्व कर सकता हूं?


हमम ... मुझे लगता है कि एक enum के सबसे नज़दीकी चीज एक शब्दकोश होगा, या तो इस तरह परिभाषित किया गया है:

months = {
    'January': 1,
    'February': 2,
    ...
}

या

months = dict(
    January=1,
    February=2,
    ...
)

फिर, आप इस तरह के स्थिरांक के लिए प्रतीकात्मक नाम का उपयोग कर सकते हैं:

mymonth = months['January']

अन्य विकल्प हैं, जैसे टुपल्स की सूची, या टुपल्स का टुपल, लेकिन शब्दकोश केवल एकमात्र ऐसा है जो आपको मूल्य तक पहुंचने के लिए "प्रतीकात्मक" (निरंतर स्ट्रिंग) तरीका प्रदान करता है।

संपादित करें: मुझे अलेक्जेंड्रू का जवाब भी पसंद है!


आपके लिए सबसे अच्छा समाधान इस बात पर निर्भर करेगा कि आपको अपने नकली enum से क्या चाहिए।

सरल enum:

यदि आपको विभिन्न वस्तुओं की पहचान करने वाले नामों की सूची के रूप में enum की आवश्यकता है, तो मार्क हैरिसन (उपरोक्त) का समाधान बहुत अच्छा है:

Pen, Pencil, Eraser = range(0, 3)

एक range का उपयोग करने से आप किसी भी प्रारंभिक मूल्य को सेट कर सकते हैं:

Pen, Pencil, Eraser = range(9, 12)

उपर्युक्त के अतिरिक्त, यदि आपको यह भी आवश्यक है कि आइटम किसी प्रकार के कंटेनर से संबंधित हों, तो उन्हें कक्षा में एम्बेड करें:

class Stationery:
    Pen, Pencil, Eraser = range(0, 3)

Enum आइटम का उपयोग करने के लिए, अब आपको कंटेनर नाम और आइटम का नाम उपयोग करने की आवश्यकता होगी:

stype = Stationery.Pen

जटिल enum:

Enum की लंबी सूची या enum के अधिक जटिल उपयोग के लिए, इन समाधानों पर्याप्त नहीं होगा। पाइथन कुकबुक में प्रकाशित पायथन में सिमुलेटिंग एन्युमरेशंस के लिए विल वेयर द्वारा नुस्खा को देख सकते हैं। इसका एक ऑनलाइन संस्करण here उपलब्ध here

और जानकारी:

पीईपी 354: पाइथन में गणनाओं में पाइथन में enum के प्रस्ताव के दिलचस्प विवरण हैं और इसे अस्वीकार क्यों किया गया था।


While the original enum proposal, PEP 354 , was rejected years ago, it keeps coming back up. Some kind of enum was intended to be added to 3.2, but it got pushed back to 3.3 and then forgotten. And now there's a PEP 435 intended for inclusion in Python 3.4. The reference implementation of PEP 435 is flufl.enum .

As of April 2013, there seems to be a general consensus that something should be added to the standard library in 3.4—as long as people can agree on what that "something" should be. That's the hard part. See the threads starting here and here , and a half dozen other threads in the early months of 2013.

Meanwhile, every time this comes up, a slew of new designs and implementations appear on PyPI, ActiveState, etc., so if you don't like the FLUFL design, try a PyPI search .


मैं क्या उपयोग करता हूं:

class Enum(object):
    def __init__(self, names, separator=None):
        self.names = names.split(separator)
        for value, name in enumerate(self.names):
            setattr(self, name.upper(), value)
    def tuples(self):
        return tuple(enumerate(self.names))

कैसे इस्तेमाल करे:

>>> state = Enum('draft published retracted')
>>> state.DRAFT
0
>>> state.RETRACTED
2
>>> state.FOO
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'Enum' object has no attribute 'FOO'
>>> state.tuples()
((0, 'draft'), (1, 'published'), (2, 'retracted'))

तो यह आपको राज्य जैसे पूर्णांक स्थिरांक देता है। प्रकाशित और दो-टुपल्स जो Django मॉडल में विकल्पों के रूप में उपयोग करने के लिए उपयोग करते हैं।


मुझे वास्तव में एलेक थॉमस का समाधान पसंद है (http://.com/a/1695250):

def enum(**enums):
    '''simple constant "enums"'''
    return type('Enum', (object,), enums)

यह सुरुचिपूर्ण और साफ दिख रहा है, लेकिन यह केवल एक ऐसा कार्य है जो निर्दिष्ट विशेषताओं वाले वर्ग बनाता है।

समारोह में थोड़ा बदलाव के साथ, हम इसे थोड़ा और 'enumy' कार्य करने के लिए प्राप्त कर सकते हैं:

नोट: मैंने pygtk की नई शैली 'enums' (जैसे Gtk.MessageType.WARNING) के व्यवहार को पुन: उत्पन्न करने का प्रयास करके निम्नलिखित उदाहरण बनाए हैं।

def enum_base(t, **enums):
    '''enums with a base class'''
    T = type('Enum', (t,), {})
    for key,val in enums.items():
        setattr(T, key, T(val))

    return T

यह एक निर्दिष्ट प्रकार के आधार पर एक enum बनाता है। पिछले फ़ंक्शन की तरह विशेषता पहुंच देने के अलावा, यह व्यवहार करता है क्योंकि आप एन्नम के प्रकारों के संबंध में अपेक्षा करेंगे। यह बेस क्लास भी प्राप्त करता है।

उदाहरण के लिए, पूर्णांक enums:

>>> Numbers = enum_base(int, ONE=1, TWO=2, THREE=3)
>>> Numbers.ONE
1
>>> x = Numbers.TWO
>>> 10 + x
12
>>> type(Numbers)
<type 'type'>
>>> type(Numbers.ONE)
<class 'Enum'>
>>> isinstance(x, Numbers)
True

इस विधि के साथ किया जा सकता है एक और दिलचस्प बात अंतर्निहित तरीकों को ओवरराइड करके विशिष्ट व्यवहार को अनुकूलित कर रही है:

def enum_repr(t, **enums):
    '''enums with a base class and repr() output'''
    class Enum(t):
        def __repr__(self):
            return '<enum {0} of type Enum({1})>'.format(self._name, t.__name__)

    for key,val in enums.items():
        i = Enum(val)
        i._name = key
        setattr(Enum, key, i)

    return Enum



>>> Numbers = enum_repr(int, ONE=1, TWO=2, THREE=3)
>>> repr(Numbers.ONE)
'<enum ONE of type Enum(int)>'
>>> str(Numbers.ONE)
'1'

पायथन में अंतर्निहित समकक्ष नहीं है, और अन्य उत्तरों में स्वयं को लागू करने के लिए विचार हैं (आप पाइथन कुकबुक में here में रुचि भी ले सकते हैं)।

हालांकि, ऐसी परिस्थितियों में जहां सी में एक enum लिए बुलाया जाएगा, मैं आमतौर पर सरल तारों का उपयोग कर समाप्त होता हूं: वस्तुओं / विशेषताओं को लागू करने के तरीके के कारण, (सी) पायथन को छोटे तारों के साथ बहुत तेजी से काम करने के लिए अनुकूलित किया जाता है, इसलिए वहां पूर्णांक का उपयोग करने के लिए वास्तव में कोई प्रदर्शन लाभ नहीं होगा। टाइपो / अमान्य मानों के खिलाफ सुरक्षा के लिए आप चयनित स्थानों में चेक डाल सकते हैं।

ANIMALS = ['cat', 'dog', 'python']

def take_for_a_walk(animal):
    assert animal in ANIMALS
    ...

(कक्षा का उपयोग करने की तुलना में एक नुकसान यह है कि आप स्वत: पूर्ण लाभ का लाभ खो देते हैं)


मैं पाइथन में enums को परिभाषित करना पसंद करता हूं:

class Animal:
  class Dog: pass
  class Cat: pass

x = Animal.Dog

यह पूर्णांक का उपयोग करने से अधिक बग-सबूत है क्योंकि आपको यह सुनिश्चित करने की चिंता करने की आवश्यकता नहीं है कि पूर्णांक अद्वितीय हैं (उदाहरण के लिए यदि आपने कुत्ता = 1 और बिल्ली = 1 कहा है तो आप खराब हो जाएंगे)।

तारों का उपयोग करने से यह अधिक बग-सबूत है क्योंकि आपको टाइपो के बारे में चिंता करने की ज़रूरत नहीं है (उदाहरण के लिए x == "catt" चुपचाप विफल रहता है, लेकिन x == Animal.Catt रनटाइम अपवाद है)।


I had need of some symbolic constants in pyparsing to represent left and right associativity of binary operators. I used class constants like this:

# an internal class, not intended to be seen by client code
class _Constants(object):
    pass


# an enumeration of constants for operator associativity
opAssoc = _Constants()
opAssoc.LEFT = object()
opAssoc.RIGHT = object()

Now when client code wants to use these constants, they can import the entire enum using:

import opAssoc from pyparsing

गणना अनूठी हैं, उन्हें '==' के बजाय 'है' के साथ परीक्षण किया जा सकता है, वे एक मामूली अवधारणा के लिए मेरे कोड में एक बड़ा पदचिह्न नहीं लेते हैं, और उन्हें आसानी से क्लाइंट कोड में आयात किया जाता है। वे किसी भी फैंसी str () व्यवहार का समर्थन नहीं करते हैं, लेकिन अभी तक YAGNI श्रेणी में है।


पीईपी 435 में वर्णित अनुसार पाइम्स 3.4 में एम्स को जोड़ा गया है। इसे पीपीआई पर 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, और 2.4 तक भी भेज दिया गया है।

अधिक उन्नत एनम तकनीक के लिए एनीम लाइब्रेरी (2.7, 3.3+, enum34 समान लेखक को enum34 । कोड पीई 2 और पी 3 के बीच पूरी तरह से संगत नहीं है, उदाहरण के लिए आपको पायथन 2 में __order__ आवश्यकता होगी)।

  • enum34 उपयोग करने के लिए, $ pip install enum34
  • aenum उपयोग करने के लिए, $ pip install aenum

enum स्थापित करना (कोई संख्या नहीं) एक पूरी तरह से अलग और असंगत संस्करण स्थापित करेगा।

from enum import Enum     # for enum34, or the stdlib version
# from aenum import Enum  # for the aenum version
Animal = Enum('Animal', 'ant bee cat dog')

Animal.ant  # returns <Animal.ant: 1>
Animal['ant']  # returns <Animal.ant: 1> (string lookup)
Animal.ant.name  # returns 'ant' (inverse lookup)

या समकक्ष:

class Animal(Enum):
    ant = 1
    bee = 2
    cat = 3
    dog = 4

पिछले संस्करणों में, enums को पूरा करने का एक तरीका है:

def enum(**enums):
    return type('Enum', (), enums)

जिसका उपयोग इस प्रकार किया जाता है:

>>> Numbers = enum(ONE=1, TWO=2, THREE='three')
>>> Numbers.ONE
1
>>> Numbers.TWO
2
>>> Numbers.THREE
'three'

आप इस तरह कुछ के साथ स्वचालित गणना आसानी से समर्थन भी कर सकते हैं:

def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    return type('Enum', (), enums)

और इस तरह इस्तेमाल किया:

>>> Numbers = enum('ZERO', 'ONE', 'TWO')
>>> Numbers.ZERO
0
>>> Numbers.ONE
1

मूल्यों को वापस नामों में परिवर्तित करने के लिए समर्थन इस तरह जोड़ा जा सकता है:

def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    reverse = dict((value, key) for key, value in enums.iteritems())
    enums['reverse_mapping'] = reverse
    return type('Enum', (), enums)

यह उस नाम के साथ कुछ भी ओवरराइट करता है, लेकिन यह आपके enums को आउटपुट में प्रस्तुत करने के लिए उपयोगी है। यदि रिवर्स मैपिंग मौजूद नहीं है तो यह KeyError फेंक देगा। पहले उदाहरण के साथ:

>>> Numbers.reverse_mapping['three']
'THREE'

Here's an approach with some different characteristics I find valuable:

  • allows > and < comparison based on order in enum, not lexical order
  • can address item by name, property or index: xa, x['a'] or x[0]
  • supports slicing operations like [:] or [-1]

and most importantly prevents comparisons between enums of different types !

Based closely on http://code.activestate.com/recipes/413486-first-class-enums-in-python .

Many doctests included here to illustrate what's different about this approach.

def enum(*names):
    """
SYNOPSIS
    Well-behaved enumerated type, easier than creating custom classes

DESCRIPTION
    Create a custom type that implements an enumeration.  Similar in concept
    to a C enum but with some additional capabilities and protections.  See
    http://code.activestate.com/recipes/413486-first-class-enums-in-python/.

PARAMETERS
    names       Ordered list of names.  The order in which names are given
                will be the sort order in the enum type.  Duplicate names
                are not allowed.  Unicode names are mapped to ASCII.

RETURNS
    Object of type enum, with the input names and the enumerated values.

EXAMPLES
    >>> letters = enum('a','e','i','o','u','b','c','y','z')
    >>> letters.a < letters.e
    True

    ## index by property
    >>> letters.a
    a

    ## index by position
    >>> letters[0]
    a

    ## index by name, helpful for bridging string inputs to enum
    >>> letters['a']
    a

    ## sorting by order in the enum() create, not character value
    >>> letters.u < letters.b
    True

    ## normal slicing operations available
    >>> letters[-1]
    z

    ## error since there are not 100 items in enum
    >>> letters[99]
    Traceback (most recent call last):
        ...
    IndexError: tuple index out of range

    ## error since name does not exist in enum
    >>> letters['ggg']
    Traceback (most recent call last):
        ...
    ValueError: tuple.index(x): x not in tuple

    ## enums must be named using valid Python identifiers
    >>> numbers = enum(1,2,3,4)
    Traceback (most recent call last):
        ...
    AssertionError: Enum values must be string or unicode

    >>> a = enum('-a','-b')
    Traceback (most recent call last):
        ...
    TypeError: Error when calling the metaclass bases
        __slots__ must be identifiers

    ## create another enum
    >>> tags = enum('a','b','c')
    >>> tags.a
    a
    >>> letters.a
    a

    ## can't compare values from different enums
    >>> letters.a == tags.a
    Traceback (most recent call last):
        ...
    AssertionError: Only values from the same enum are comparable

    >>> letters.a < tags.a
    Traceback (most recent call last):
        ...
    AssertionError: Only values from the same enum are comparable

    ## can't update enum after create
    >>> letters.a = 'x'
    Traceback (most recent call last):
        ...
    AttributeError: 'EnumClass' object attribute 'a' is read-only

    ## can't update enum after create
    >>> del letters.u
    Traceback (most recent call last):
        ...
    AttributeError: 'EnumClass' object attribute 'u' is read-only

    ## can't have non-unique enum values
    >>> x = enum('a','b','c','a')
    Traceback (most recent call last):
        ...
    AssertionError: Enums must not repeat values

    ## can't have zero enum values
    >>> x = enum()
    Traceback (most recent call last):
        ...
    AssertionError: Empty enums are not supported

    ## can't have enum values that look like special function names
    ## since these could collide and lead to non-obvious errors
    >>> x = enum('a','b','c','__cmp__')
    Traceback (most recent call last):
        ...
    AssertionError: Enum values beginning with __ are not supported

LIMITATIONS
    Enum values of unicode type are not preserved, mapped to ASCII instead.

    """
    ## must have at least one enum value
    assert names, 'Empty enums are not supported'
    ## enum values must be strings
    assert len([i for i in names if not isinstance(i, types.StringTypes) and not \
        isinstance(i, unicode)]) == 0, 'Enum values must be string or unicode'
    ## enum values must not collide with special function names
    assert len([i for i in names if i.startswith("__")]) == 0,\
        'Enum values beginning with __ are not supported'
    ## each enum value must be unique from all others
    assert names == uniquify(names), 'Enums must not repeat values'

    class EnumClass(object):
        """ See parent function for explanation """

        __slots__ = names

        def __iter__(self):
            return iter(constants)

        def __len__(self):
            return len(constants)

        def __getitem__(self, i):
            ## this makes xx['name'] possible
            if isinstance(i, types.StringTypes):
                i = names.index(i)
            ## handles the more normal xx[0]
            return constants[i]

        def __repr__(self):
            return 'enum' + str(names)

        def __str__(self):
            return 'enum ' + str(constants)

        def index(self, i):
            return names.index(i)

    class EnumValue(object):
        """ See parent function for explanation """

        __slots__ = ('__value')

        def __init__(self, value):
            self.__value = value

        value = property(lambda self: self.__value)

        enumtype = property(lambda self: enumtype)

        def __hash__(self):
            return hash(self.__value)

        def __cmp__(self, other):
            assert self.enumtype is other.enumtype, 'Only values from the same enum are comparable'
            return cmp(self.value, other.value)

        def __invert__(self):
            return constants[maximum - self.value]

        def __nonzero__(self):
            ## return bool(self.value)
            ## Original code led to bool(x[0])==False, not correct
            return True

        def __repr__(self):
            return str(names[self.value])

    maximum = len(names) - 1
    constants = [None] * len(names)
    for i, each in enumerate(names):
        val = EnumValue(i)
        setattr(EnumClass, each, val)
        constants[i] = val
    constants = tuple(constants)
    enumtype = EnumClass()
    return enumtype

PyPI से enum पैकेज enums के एक मजबूत कार्यान्वयन प्रदान करता है। एक पूर्व उत्तर पीईपी 354 का उल्लेख किया; इसे खारिज कर दिया गया था लेकिन प्रस्ताव लागू किया गया था http://pypi.python.org/pypi/enum

उपयोग आसान और सुरुचिपूर्ण है:

>>> from enum import Enum
>>> Colors = Enum('red', 'blue', 'green')
>>> shirt_color = Colors.green
>>> shirt_color = Colors[2]
>>> shirt_color > Colors.red
True
>>> shirt_color.index
2
>>> str(shirt_color)
'green'

def M_add_class_attribs(attribs):
    def foo(name, bases, dict_):
        for v, k in attribs:
            dict_[k] = v
        return type(name, bases, dict_)
    return foo

def enum(*names):
    class Foo(object):
        __metaclass__ = M_add_class_attribs(enumerate(names))
        def __setattr__(self, name, value):  # this makes it read-only
            raise NotImplementedError
    return Foo()

इसे इस तरह प्रयोग करें:

Animal = enum('DOG', 'CAT')
Animal.DOG # returns 0
Animal.CAT # returns 1
Animal.DOG = 2 # raises NotImplementedError

यदि आप केवल अद्वितीय प्रतीक चाहते हैं और मूल्यों की परवाह नहीं करते हैं, तो इस पंक्ति को प्रतिस्थापित करें:

__metaclass__ = M_add_class_attribs(enumerate(names))

इसके साथ:

__metaclass__ = M_add_class_attribs((object(), name) for name in names)

यहां एलेक थॉमस के समाधान पर एक संस्करण है:

def enum(*args, **kwargs):
    return type('Enum', (), dict((y, x) for x, y in enumerate(args), **kwargs)) 

x = enum('POOH', 'TIGGER', 'EEYORE', 'ROO', 'PIGLET', 'RABBIT', 'OWL')
assert x.POOH == 0
assert x.TIGGER == 1

यदि आपको संख्यात्मक मानों की आवश्यकता है, तो यहां सबसे तेज़ तरीका है:

dog, cat, rabbit = range(3)

पायथन 3.x में आप अंत में एक तारांकित प्लेसहोल्डर भी जोड़ सकते हैं, जो कि रेंज के सभी शेष मूल्यों को भंग कर देगा यदि आपको स्मृति बर्बाद करने में कोई फर्क नहीं पड़ता है और यह गिनती नहीं कर सकता है:

dog, cat, rabbit, horse, *_ = range(100)

एक एनम कक्षा एक लाइनर हो सकती है।

class Enum(tuple): __getattr__ = tuple.index

इसका उपयोग कैसे करें (आगे बढ़ें और लुकअप, चाबियाँ, मान, आइटम इत्यादि)

>>> State = Enum(['Unclaimed', 'Claimed'])
>>> State.Claimed
1
>>> State[1]
'Claimed'
>>> State
('Unclaimed', 'Claimed')
>>> range(len(State))
[0, 1]
>>> [(k, State[k]) for k in range(len(State))]
[(0, 'Unclaimed'), (1, 'Claimed')]
>>> [(k, getattr(State, k)) for k in State]
[('Unclaimed', 0), ('Claimed', 1)]

इसे सरल रखें:

class Enum(object): 
    def __init__(self, tupleList):
            self.tupleList = tupleList

    def __getattr__(self, name):
            return self.tupleList.index(name)

फिर:

DIRECTION = Enum(('UP', 'DOWN', 'LEFT', 'RIGHT'))
DIRECTION.DOWN
1

डेविड ने डिक्ट्स का उपयोग करने की सिफारिश की। मैं एक कदम आगे जाऊंगा और सेट का उपयोग करूंगा:

months = set('January', 'February', ..., 'December')

अब आप यह जांच सकते हैं कि कोई मान सेट में मानों में से किसी एक से मेल खाता है या नहीं:

if m in months:

डीएफ की तरह, हालांकि, मैं आम तौर पर केवल enums के स्थान पर स्ट्रिंग स्थिरांक का उपयोग करता हूं।


2013-05-10 को, गिडो पीईपी 435 को पाइथन 3.4 मानक पुस्तकालय में स्वीकार करने पर सहमत हुए। इसका मतलब है कि पाइथन ने अंततः गणनाओं के लिए समर्थन दिया है!

पाइथन 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, और 2.4 के लिए एक बैकपोर्ट उपलब्ध है। यह enp34 के रूप में Pypi पर है

घोषणा:

>>> from enum import Enum
>>> class Color(Enum):
...     red = 1
...     green = 2
...     blue = 3

प्रतिनिधित्व:

>>> print(Color.red)
Color.red
>>> print(repr(Color.red))
<Color.red: 1>

पुनरावृत्ति:

>>> for color in Color:
...   print(color)
...
Color.red
Color.green
Color.blue

प्रोग्रामेटिक एक्सेस:

>>> Color(1)
Color.red
>>> Color['blue']
Color.blue

अधिक जानकारी के लिए , प्रस्ताव का संदर्भ लें। आधिकारिक दस्तावेज शायद जल्द ही पालन करेंगे।


यह समाधान एक सूची के रूप में परिभाषित गणना के लिए कक्षा प्राप्त करने का एक आसान तरीका है (कोई और कष्टप्रद पूर्णांक असाइनमेंट नहीं):

enumeration.py:

import new

def create(class_name, names):
    return new.classobj(
        class_name, (object,), dict((y, x) for x, y in enumerate(names))
    )

example.py:

import enumeration

Colors = enumeration.create('Colors', (
    'red',
    'orange',
    'yellow',
    'green',
    'blue',
    'violet',
))

जावा प्री-जेडीके 5 में इस्तेमाल किए जाने वाले टाइपएफ़ एनम पैटर्न में कई फायदे हैं। अलेक्जेंड्रू के उत्तर में बहुत पसंद है, आप एक वर्ग और वर्ग स्तर के खेतों को enum मूल्य बनाते हैं; हालांकि, enum मूल्य छोटे पूर्णांक की बजाय कक्षा के उदाहरण हैं। इसका लाभ यह है कि आपके enum मान अनजाने में छोटे पूर्णांक के बराबर तुलना नहीं करते हैं, आप नियंत्रित कर सकते हैं कि वे कैसे मुद्रित होते हैं, अगर यह उपयोगी है और मनोविज्ञान का उपयोग करके मनमानी तरीके जोड़ें,

class Animal:
   def __init__(self, name):
       self.name = name

   def __str__(self):
       return self.name

   def __repr__(self):
       return "<Animal: %s>" % self

Animal.DOG = Animal("dog")
Animal.CAT = Animal("cat")

>>> x = Animal.DOG
>>> x
<Animal: dog>
>>> x == 1
False

पाइथन-देव पर एक हालिया धागे ने बताया कि जंगली में कुछ enum पुस्तकालय हैं, जिनमें शामिल हैं:


एम्स के लिए कक्षा स्थिरांक का उपयोग करने के अलेक्जेंड्रू का सुझाव काफी अच्छा काम करता है।

मैं मानव-पठनीय स्ट्रिंग प्रस्तुति को देखने के लिए स्थिरांक के प्रत्येक सेट के लिए एक शब्दकोश जोड़ना भी पसंद करता हूं।

यह दो उद्देश्यों को पूरा करता है: ए) यह आपके enum को सुंदर प्रिंट करने का एक आसान तरीका प्रदान करता है और बी) शब्दकोश तार्किक रूप से स्थिरांक समूह बनाता है ताकि आप सदस्यता के लिए परीक्षण कर सकें।

class Animal:    
  TYPE_DOG = 1
  TYPE_CAT = 2

  type2str = {
    TYPE_DOG: "dog",
    TYPE_CAT: "cat"
  }

  def __init__(self, type_):
    assert type_ in self.type2str.keys()
    self._type = type_

  def __repr__(self):
    return "<%s type=%s>" % (
        self.__class__.__name__, self.type2str[self._type].upper())

यह मैंने देखा है सबसे अच्छा है: "पायथन में प्रथम श्रेणी Enums"

यह आपको एक कक्षा देता है, और कक्षा में सभी enums शामिल हैं। Enums की तुलना एक दूसरे से की जा सकती है, लेकिन कोई विशेष मूल्य नहीं है; आप उन्हें एक पूर्णांक मान के रूप में उपयोग नहीं कर सकते हैं। (मैंने पहले इसका विरोध किया क्योंकि मुझे सी एनम्स के लिए उपयोग किया जाता है, जो पूर्णांक मान हैं। लेकिन यदि आप इसे पूर्णांक के रूप में उपयोग नहीं कर सकते हैं, तो आप इसे गलती से पूर्णांक के रूप में उपयोग नहीं कर सकते हैं, इसलिए मुझे लगता है कि यह एक जीत है ।) प्रत्येक enum एक अद्वितीय मूल्य है। आप enums प्रिंट कर सकते हैं, आप उन पर फिर से शुरू कर सकते हैं, आप परीक्षण कर सकते हैं कि enum मान enum में "in" है। यह बहुत सुंदर और चिकना है।

संपादित करें (सीएफआई): उपरोक्त लिंक पायथन 3 संगत नहीं है। पायथन 3 पर enum.py का मेरा बंदरगाह यहां है:

def cmp(a,b):
   if a < b: return -1
   if b < a: return 1
   return 0


def Enum(*names):
   ##assert names, "Empty enums are not supported" # <- Don't like empty enums? Uncomment!

   class EnumClass(object):
      __slots__ = names
      def __iter__(self):        return iter(constants)
      def __len__(self):         return len(constants)
      def __getitem__(self, i):  return constants[i]
      def __repr__(self):        return 'Enum' + str(names)
      def __str__(self):         return 'enum ' + str(constants)

   class EnumValue(object):
      __slots__ = ('__value')
      def __init__(self, value): self.__value = value
      Value = property(lambda self: self.__value)
      EnumType = property(lambda self: EnumType)
      def __hash__(self):        return hash(self.__value)
      def __cmp__(self, other):
         # C fans might want to remove the following assertion
         # to make all enums comparable by ordinal value {;))
         assert self.EnumType is other.EnumType, "Only values from the same enum are comparable"
         return cmp(self.__value, other.__value)
      def __lt__(self, other):   return self.__cmp__(other) < 0
      def __eq__(self, other):   return self.__cmp__(other) == 0
      def __invert__(self):      return constants[maximum - self.__value]
      def __nonzero__(self):     return bool(self.__value)
      def __repr__(self):        return str(names[self.__value])

   maximum = len(names) - 1
   constants = [None] * len(names)
   for i, each in enumerate(names):
      val = EnumValue(i)
      setattr(EnumClass, each, val)
      constants[i] = val
   constants = tuple(constants)
   EnumType = EnumClass()
   return EnumType


if __name__ == '__main__':
   print( '\n*** Enum Demo ***')
   print( '--- Days of week ---')
   Days = Enum('Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su')
   print( Days)
   print( Days.Mo)
   print( Days.Fr)
   print( Days.Mo < Days.Fr)
   print( list(Days))
   for each in Days:
      print( 'Day:', each)
   print( '--- Yes/No ---')
   Confirmation = Enum('No', 'Yes')
   answer = Confirmation.No
   print( 'Your answer is not', ~answer)

पायथन 3.4 से enums के लिए आधिकारिक समर्थन होगा। आप पाइथन 3.4 दस्तावेज़ीकरण पृष्ठ पर यहां दस्तावेज़ और उदाहरण पा सकते हैं।

कक्षा वाक्य वाक्यविन्यास का उपयोग करके गणनाएं बनाई गई हैं, जो उन्हें पढ़ने और लिखने में आसान बनाती हैं। कार्यात्मक एपीआई में एक वैकल्पिक निर्माण विधि का वर्णन किया गया है। एक गणना को परिभाषित करने के लिए, उपclass Enum निम्नानुसार है:

from enum import Enum
class Color(Enum):
     red = 1
     green = 2
     blue = 3

पीईपी 435 से पहले, पायथन के बराबर नहीं था लेकिन आप अपना खुद का कार्यान्वयन कर सकते थे।

खुद, मुझे इसे सरल रखना पसंद है (मैंने नेट पर कुछ जटिल जटिल उदाहरण देखे हैं), ऐसा कुछ ...

class Animal:
    DOG = 1
    CAT = 2

x = Animal.DOG

पायथन 3.4 ( पीईपी 435 ) में, आप एनम बेस श्रेणी बना सकते हैं। यह आपको पीईपी में वर्णित अतिरिक्त कार्यक्षमता का थोड़ा सा हिस्सा देता है। उदाहरण के लिए, enum मान पूर्णांक से अलग हैं।

class Animal(Enum):
    DOG = 1
    CAT = 2

print(Animal.DOG)
<Animal.DOG: 1>

यदि आप मान टाइप नहीं करना चाहते हैं, तो निम्न शॉर्टकट का उपयोग करें:

class Animal(Enum):
    DOG, CAT = range(2)






enums