如何在Python中声明常量?

在Java中,我们做:

public static final String CONST_NAME = "Name";

当前回答

在python中,常量只是一个变量,名称全大写,单词之间用下划线分隔,

e.g

Days_in_week = 7

该值是可变的,即您可以更改它。但既然名字的规则告诉你是常数,你为什么要这么做呢?我是说,这毕竟是你的项目!

这是python中采用的方法。出于同样的原因,没有private关键字。用下划线作为名称的前缀,您就知道它是私有的。代码可以打破规则....就像程序员可以删除private关键字一样。

Python可以添加一个const关键字…但是程序员可以删除关键字,然后如果他们想要更改常量,但为什么要这样做呢?如果你想打破规则,你可以改变规则。但如果名字的意思已经很清楚了,为什么还要费心打破规则呢?

也许在某些单元测试中,对值应用更改是有意义的?看看一周8天会发生什么,尽管在现实世界中,一周的天数是不能改变的。如果语言阻止你做一个例外,如果只有这一个情况,你需要打破规则……然后您将不得不停止将它声明为常量,即使它在应用程序中仍然是常量,并且只有这个测试用例来查看如果它被更改会发生什么。

全大写的名称告诉您它是一个常量。这才是重要的。没有一种语言强制约束代码,无论如何你都可以修改。

这就是python的哲学。

其他回答

python声明“常量”的方式基本上是一个模块级别的变量:

RED = 1
GREEN = 2
BLUE = 3

然后编写类或函数。因为常量几乎都是整数,而且它们在Python中也是不可变的,所以你几乎没有机会改变它。

当然,除非显式地设置RED = 2。

我们可以创建一个描述符对象。

class Constant:
  def __init__(self,value=None):
    self.value = value
  def __get__(self,instance,owner):
    return self.value
  def __set__(self,instance,value):
    raise ValueError("You can't change a constant")

1)如果我们想在实例级使用常量,那么:

class A:
  NULL = Constant()
  NUM = Constant(0xFF)

class B:
  NAME = Constant('bar')
  LISTA = Constant([0,1,'INFINITY'])

>>> obj=A()
>>> print(obj.NUM)  #=> 255
>>> obj.NUM =100

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: You can't change a constant

2)如果我们只想在类级别上创建常量,我们可以使用元类作为常量(描述符对象)的容器;所有下降的类将继承我们的常量(我们的描述符对象),没有任何可以修改的风险。

# metaclass of my class Foo
class FooMeta(type): pass

# class Foo
class Foo(metaclass=FooMeta): pass

# I create constants in my metaclass
FooMeta.NUM = Constant(0xff)
FooMeta.NAME = Constant('FOO')

>>> Foo.NUM   #=> 255
>>> Foo.NAME  #=> 'FOO'
>>> Foo.NUM = 0 #=> ValueError: You can't change a constant

如果我创建一个Foo的子类,这个类将继承常量,而不可能修改它们

class Bar(Foo): pass

>>> Bar.NUM  #=> 255
>>> Bar.NUM = 0  #=> ValueError: You can't change a constant

除了上面的两个答案(只使用大写的变量名,或者使用属性使值为只读),我想提到的是,可以使用元类来实现命名常量。我在GitHub提供了一个使用元类的非常简单的解决方案,如果你想让值的类型/名称更有信息,这可能会很有帮助:

>>> from named_constants import Constants
>>> class Colors(Constants):
...     black = 0
...     red = 1
...     white = 15
...
>>> c = Colors.black
>>> c == 0
True
>>> c
Colors.black
>>> c.name()
'black'
>>> Colors(0) is c
True

这是稍微高级一些的Python,但仍然非常容易使用和方便。(该模块有更多的特性,包括常量是只读的,请参阅它的README。)

在各种存储库中也有类似的解决方案,但据我所知,它们要么缺乏我对常量所期望的基本特性之一(比如是常量,或者是任意类型),要么添加了一些深奥的特性,使它们不那么普遍适用。但是YMMV,我很感激你的反馈。: -)

在Python中,人们使用命名约定,例如私有方法使用__method,受保护方法使用_method。

所以用同样的方式,你可以简单地将常量声明为全大写,例如:

MY_CONSTANT = "one"

如果你想让这个常量永远不变,你可以挂钩到属性访问并做一些技巧,但更简单的方法是声明一个函数:

def MY_CONSTANT():
    return "one"

唯一的问题是,在任何地方都必须执行MY_CONSTANT(),但MY_CONSTANT = "one"在Python中是正确的方式(通常)。


你也可以使用namedtuple()来创建常量:

>>> from collections import namedtuple
>>> Constants = namedtuple('Constants', ['pi', 'e'])
>>> constants = Constants(3.14, 2.718)
>>> constants.pi
3.14
>>> constants.pi = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
from enum import Enum
class StringConsts(str,Enum):
    ONE='one'
    TWO='two'

print(f'Truth is  {StringConsts.ONE=="one"}') #Truth is True
StringConsts.ONE="one" #Error: Cannot reassign

Enum和str的混合让你不必重新实现setattr(通过Enum),也不必与其他str对象进行比较(通过str)。

这可能会使http://code.activestate.com/recipes/65207-constants-in-python/?in=user-97991完全弃用。