在python中分组常量

Mar*_*ero 8 python coding-style namespaces constants python-2.7

这主要是一个"好蟒蛇风格"的问题.

我有一个模块,它使用了许多应该被分组的常量.

让我们说我们有狗和猫,每个人都有腿和最喜欢的食物.

注意

  1. 我们想要模拟关于狗和猫的常数
  2. 很可能我们将来会有更多的动物.
  3. 这些常量不会在当前模块之外使用.

我想到了以下解决方案:


模块级别的常量

DOG_NUMBER_OF_LEGS = 4
DOG_FAVOURITE_FOOD = ["Socks", "Meat"]
CAT_NUMBER_OF_LEGS = 4
CAT_FAVOURITE_FOOD = ["Lasagna", "Fish"]
Run Code Online (Sandbox Code Playgroud)

他们似乎没有真正分组,但我认为这是我更喜欢的解决方案.


类作为命名空间

class Dog(object):
  NUMBER_OF_LEGS = 4
  DOG_FAVOURITE_FOOD = ["Socks", "Meat"]
class Cat(object):
  NUMBER_OF_LEGS = 4
  FAVOURITE_FOOD = ["Lasagna", "Fish"]
Run Code Online (Sandbox Code Playgroud)

我不喜欢这个解决方案,因为我们将拥有不会使用的类,并且它们可以实际实例化.


常量字典

ANIMALS_CONFIG = { 
   "DOG" : { 
     "NUMBER_OF_LEGS" : 4,
     "FAVOURITE_FOOD" : ["Socks", "Meat"]
   },
   "CAT" : { 
     "NUMBER_OF_LEGS" : 4,
     "FAVOURITE_FOOD" : ["Lasagna", "Fish"]
   }
}
Run Code Online (Sandbox Code Playgroud)

我还想过添加子模块,但我真的不想暴露那些内部常量


最狡猾的方式是什么/你会怎么做?

jon*_*rpe 6

我会选择第四种选择,更喜欢collections.namedtuple:

Animal = namedtuple('Animal', 'number_of_legs favourite_food')
Run Code Online (Sandbox Code Playgroud)

然后创建如下的实例:

DOG = Animal(4, ['Socks', 'Meat'])
CAT = Animal(4, ['Lasagna', 'Fish'])
Run Code Online (Sandbox Code Playgroud)

并在外部访问值:

from animals import CAT

print CAT.number_of_legs
Run Code Online (Sandbox Code Playgroud)

如果你不需要创建任何方法,那么拥有类是没有意义的,我认为上面的访问形式比例如:

from animals import animals

print animals['CAT']['number_of_legs']
Run Code Online (Sandbox Code Playgroud)

namedtuples,像香草一样tuple,也是不可改变的,所以你不能在CAT.number_of_legs = 2某处意外重新分配.

最后,这namedtuple是一个轻量级的数据结构,如果你创造了很多动物,这可能很重要:

>>> import sys
>>> sys.getsizeof({'number_of_legs': 4, 'favourite_food': ['Lasagna', 'Fish']})
140
>>> from collections import namedtuple
>>> Animal = namedtuple('Animal', 'number_of_legs favourite_food')
>>> sys.getsizeof(Animal(4, ['Lasagna', 'Fish']))
36
Run Code Online (Sandbox Code Playgroud)