2

I want a enum with predefined single character constants (good for storing in database) and string interpretation. Here is what I am thinking of:

class Fruits(Enum):
    APPLE = 'A'
    PEAR = 'P'
    BANANA = 'B'
    def __unicode__(self):
        if self == APPLE: return "Crunchy Apple"
        if self == PEAR: return "Sweet Pear"
        if self == BANANA: return "Long Banana"

But

fruit = Fruits.APPLE
print fruit.__unicode__()

gives

AttributeError: 'unicode' object has no attribute '__unicode__'

And besides there must be a more elegant way of doing it

How to do it better?

3
  • You appear to be using Python2. Can you confirm whether you are using Python2 or Python3? (You can examine sys.version to be sure.) Commented Mar 24, 2016 at 18:06
  • Where did Fruits.TYPE_APPLE come from? You only defined Fruits.APPLE. If you retyped the code in the question from memory, copy-paste it from a file you've actually run or an actual interactive session next time. Commented Mar 24, 2016 at 18:10
  • @Rob I am more interested in Python 2 Commented Mar 24, 2016 at 18:12

2 Answers 2

5

A couple observations:

  • You shouldn't call __dunder__ methods directly; instead use the matching command: unicode instead of __unicode__

  • I am unable to duplicate your problem

Using the stdlib Enum (3.4+) or the enum34 backport (Python 2.x) you will have to do it the hard way -- make your own base Enum class:

class EnumWithDescription(Enum):
    def __new__(cls, value, desc):
        member = object.__new__(cls)
        member._value_ = value
        member.description = desc
        return member
    def __unicode__(self):
        return self.description

class Fruits(EnumWithDescription):
    _order_ = 'APPLE PEAR BANANA'   # if using Python 2.x and order matters
    APPLE = 'A', 'Crunchy Apple'
    PEAR = 'P', 'Sweet Pear'
    BANANA = 'B', 'Long Banana'

and in use:

>>> fruit = Fruits.APPLE
>>> unicode(fruit)
u'Crunchy Apple'

If you can use the aenum library1 you will have an easier time of it:

from aenum import Enum

class Fruits(Enum, init='value description'):
    APPLE = 'A', 'Crunchy Apple'
    PEAR = 'P', 'Sweet Pear'
    BANANA = 'B', 'Long Banana'
    def describe(self):
        return self.description

and in use:

fruit = Fruits.APPLE
fruit.describe()

Note that since unicode is the default in Python 3 I changed the name to describe.


1 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

Sign up to request clarification or add additional context in comments.

Comments

-1

The enum34 module has what you want.

from enum import Enum

class Fruits(Enum):
    apple = 'A'
    pear = 'P'
    banana = 'B'

fruit = Fruits.apple

print fruit.value
>> 'A'

Possibly even better is using integers

from enum import Enum

class Fruits(Enum):
    apple = 1
    pear = 2
    banana = 3

fruit = Fruits.apple

print fruit.value
>> 1

And recreate the object if you get it's value (from a database for instance) using:

fruit = Fruits(1)

2 Comments

This doesn't answer the OP's question.
Ah you're actually correct I think. But there's also fruit.name for the requested sting interpretation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.