【问题标题】:Per-class constants in PythonPython中的每类常量
【发布时间】:2015-07-28 14:20:10
【问题描述】:

另一个 Python 代码风格问题。

如果我有一些适用于单个类的“常量值”(引用是因为 Python 中没有这样的东西),那么首选是什么:模块级变量或类变量?

例如假设我们有一个类Counter,它在达到恒定阈值时会做一些事情,这是首选?

class Counter(object):
    THRESHOLD = 6
    ...

    def increment(self):
        self.val += 1
        if self.val == Counter.THRESHOLD:
            do_something()

或:

COUNTER_THRESHOLD = 6

class Counter(object):
    ...
    def increment(self):
        self.val += 1
        if self.val == COUNTER_THRESHOLD:
            do_something()

我唯一能找到的就是 Python 文档。他们建议将类变量理想地视为“常量”:

类变量可以用作实例变量的默认值,但是 在那里使用可变值可能会导致意想不到的结果。

https://docs.python.org/2/reference/compound_stmts.html#class-definitions

但是,这并不能真正回答问题。 编辑:正如@JBernardo 指出的那样,这是无关紧要的,因为它指的是可变数据类型,而不是可变变量值。

想法?

谢谢

【问题讨论】:

  • 如果只有一个类需要它,把它放在类中可以保持模块命名空间干净。请注意,您可以通过self.THRESHOLD 访问它,这将更巧妙地处理继承。此外,文档中的引用并没有说明您声称它的作用 - 不变性与被视为常量不同。
  • 我同意@jonrsharpe 将其保留在类中,以便它充当命名空间并提供常量上下文
  • 在此上下文中的“可变值”不是“可变值”。我的意思是你不应该使用列表和字典(以及许多其他可变对象),除非你知道你在做什么。否则,请始终将值放在类中。
  • 感谢您的反馈和self. 提示。我会再把这个问题留一会儿,看看其他人的想法。
  • 我同意@JBernardo,与self.THRESHOLD一起使用时要小心,它首先查找实例var,然后查找类var,您可以在保持类的同时操作实例变量self.THRESHOLD var 完整

标签: python coding-style


【解决方案1】:

绝对保留它作为类的成员,它更清晰,更整洁。

您可以拥有多个类,每个类都有一个您不会干扰的阈值(更不用说对阈值的全局命名空间引用)。阅读classname.THRESHOLD 会更清楚,因为这表明了意图的实际含义。

而且,它对于进口来说要好得多。如果你使用

from file import classname

仅当阈值实际上位于类的命名空间中时,您才会保留阈值,而在导入特定类/函数时会忽略全局命名空间变量。

演示:

Classy.py

glob = "global"

class ClassName:
    name = "Class Name"

其他文件.py

from classy import ClassName

print ClassName.name
print glob

运行Otherfile.py的结果

Class Name

Traceback (most recent call last):
  File "C:\Users\person\Desktop\otherfile.py", line 4, in <module>
    print glob
NameError: name 'glob' is not defined

【讨论】:

  • 不破坏开闭原则吗?假设常量是类操作的文件列表,并且您想要添加一个新文件。在一个类中拥有这样的常量会让你在这种情况下改变类,即使类的逻辑没有改变。
【解决方案2】:

如果它只适用于类,它应该只对类可见。

【讨论】:

    猜你喜欢
    • 2012-05-27
    • 2020-05-11
    • 2014-11-21
    • 1970-01-01
    • 2014-06-07
    • 2018-01-24
    • 2012-02-12
    • 2015-04-21
    • 2014-04-09
    相关资源
    最近更新 更多