2013-02-28 1 views
1

Я определяю модели для своего приложения, и мне нужен столбец с именем «статус» для различных процедур проверки. Вот упрощенная модель пользователя.Избегание магических чисел в Python Flask и, возможно, большинство других языков

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

Я попросил разработчика Python просмотреть мой код; и он предположил, что я избегал «магических чисел». Его решение таково:

 
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"), 
    ) 

Не мог ли я использовать простые словари вместо этого? Кто-нибудь видит вескую причину для «классного» решения?

+1

Как насчет этого http://stackoverflow.com/a/4472993/1481060 – sotapme

+0

Я использую такие вещи довольно часто. Однако я думал о http://docs.python.org/2/library/collections.html#collections.namedtuple. Я думаю, что это лучшая идея, чем диктофон, поскольку вы не набираете строки. – YXD

+0

Я начинающий программист, поэтому более простые решения имеют больше смысла. Похоже, если я хочу использовать один способ выбора номера, то словарь достаточно хорош. Однако, если программа требует второго противоположного направления int для функции string, тогда было бы лучшим выбором пойти с основанием класса. –

ответ

2

Строительство на 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 Добавлено создать метод класса, так что строка может быть использована для создания перечислений.

Хотя есть, вероятно, лучшие решения.

Смежные вопросы