Dogukan Tufekci
Dogukan Tufekci

Reputation: 3108

Avoiding magic numbers in Python Flask and probably most other languages

I am defining models for my app and I need to a column named 'status' for various verification procedures. Here is a simplified user model.

class User
    id(int)
    name(str)
    status(int) # 0- New 1-Active 2-Inactive 3-Reported 4-Deleted

I asked a fellow Python developer to review my code; and he suggested that I avoided 'magic numbers'. His solution is this:

class Choices:
    @classmethod
    def get_value(cls, key):
        # get the string display if need to show
        for k, v in cls.CHOICES:
            if k == key:
                return v
        return ""

class UserStatusChoices(Choices):
    NEW = 0
    ACTIVE = 1
    INACTIVE = 2
    REPORTED = 3
    DELETED = 4

    CHOICES = (
        (NEW, "NEW"),
        (ACTIVE, "ACTIVE"),
        (INACTIVE, "INACTIVE"),
        (REPORTED, "REPORTED"),
        (DELETED, "DELETED"),
    )

Couldn't I use simple dictionaries instead? Does anyone see a good reason for 'class'y solution?

Upvotes: 1

Views: 1210

Answers (1)

sotapme
sotapme

Reputation: 4903

Building on Python Enum class (with tostring fromstring)

class Enum(object):
    @classmethod
    def tostring(cls, val):
        for k,v in vars(cls).iteritems():
            if v==val:
                return k

    @classmethod
    def fromstring(cls, str):
        return getattr(cls, str.upper(), None)

    @classmethod
    def build(cls, str):
        for val, name in enumerate(str.split()):
            setattr(cls, name, val)
class MyEnum(Enum):
    VAL1, VAL2, VAL3 = range(3)

class YourEnum(Enum):
    CAR, BOAT, TRUCK = range(3)

class MoreEnum(Enum):
    pass

print MyEnum.fromstring('Val1')
print MyEnum.tostring(2)
print MyEnum.VAL1 

print YourEnum.BOAT
print YourEnum.fromstring('TRUCK')

# Dodgy semantics for creating enums.
# Should really be
# MoreEnum = Enum.build("CIRCLE SQUARE")
MoreEnum.build("CIRCLE SQUARE")
print MoreEnum.CIRCLE
print MoreEnum.tostring(1)
print MoreEnum.tostring(MoreEnum.CIRCLE)

EDIT Added build class method so that a string could be used to build the enums.

Although there are probably better solutions out there.

Upvotes: 3

Related Questions