【问题标题】:Grouping constants in pythonpython中的分组常量
【发布时间】:2015-06-29 19:02:52
【问题描述】:

这主要是一个“好的python风格”的问题。

我有一个模块,它使用了一些感觉应该分组的常量。

假设我们有狗和猫,他们每个人都有许多腿和最喜欢的食物。

注意

  1. 我们只想建模关于 Dogs 和 Cats 的常量
  2. 很可能我们将来会有更多的动物。
  3. 这些常量不会在当前模块之外使用。

我想到了以下解决方案:


模块级别的常量

DOG_NUMBER_OF_LEGS = 4
DOG_FAVOURITE_FOOD = ["Socks", "Meat"]
CAT_NUMBER_OF_LEGS = 4
CAT_FAVOURITE_FOOD = ["Lasagna", "Fish"]

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


作为命名空间的类

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

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


常量字典

ANIMALS_CONFIG = { 
   "DOG" : { 
     "NUMBER_OF_LEGS" : 4,
     "FAVOURITE_FOOD" : ["Socks", "Meat"]
   },
   "CAT" : { 
     "NUMBER_OF_LEGS" : 4,
     "FAVOURITE_FOOD" : ["Lasagna", "Fish"]
   }
}

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


最pythonic的方法是什么/你会怎么做?

【问题讨论】:

  • 你也可以有一个类 Animaldogcat 该类的实例。
  • 或者你也可以使用named tuples
  • 你将如何在你的代码中使用它们?你会迭代还是选择?选择参数从哪里来?
  • 没有迭代或类似的东西。只是用全名称呼我的常数。 DOG_NUMBER_OF_LEGS 、 ANIMALS_CONFIG["DOG"]["NUMBER_OF_LEGS"] 或 Dog.NUMBER_OF_LEGS
  • @MarioA.CorcheroJiménez 只是为了确认一下,您希望对象的唯一行为是保存这两个值并通过键和/或属性访问它们?跨度>

标签: python python-2.7 namespaces coding-style constants


【解决方案1】:

我会选择第四个选项,更喜欢collections.namedtuple

Animal = namedtuple('Animal', 'number_of_legs favourite_food')

然后您创建如下实例:

DOG = Animal(4, ['Socks', 'Meat'])
CAT = Animal(4, ['Lasagna', 'Fish'])

并以如下方式从外部访问值:

from animals import CAT

print CAT.number_of_legs

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

from animals import animals

print animals['CAT']['number_of_legs']

namedtuples 和 vanilla tuples 一样,也是不可变的,因此您不会意外重新分配,例如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

【讨论】:

    【解决方案2】:

    没有一刀切的答案,这实际上取决于您必须处理多少常量、如何使用它们、多态调度是否有意义以及月相。

    现在在您的示例中,由于您有两组或多组具有相似结构和含义的常量,我会选择“作为命名空间的类”解决方案。

    FWIW 阻止类被实例化并不难:

    >>> class Foo(object):
    ...    def __new__(cls):
    ...       return cls
    ... 
    >>> Foo()
    <class '__main__.Foo'>
    

    但文档应该就足够了 - 请记住,无论如何,您的“常量”只是约定的常量。

    【讨论】:

      【解决方案3】:

      我会选择字典的方法,因为它感觉更易读且更有条理,但我相信这是个人喜好问题。

      如果您使用仅包含静态变量和方法的类(如 this)并且您从不实例化它们,那么使用类似乎也不是一个坏主意。

      【讨论】:

        猜你喜欢
        • 2020-08-20
        • 1970-01-01
        • 1970-01-01
        • 2020-11-18
        • 2012-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多