如何在Python中声明常量?

在Java中,我们做:

public static final String CONST_NAME = "Name";

当前回答

这里有一个技巧,如果你想要常量,而不关心它们的值:

只定义空类。

e.g:

class RED: 
    pass
class BLUE: 
    pass

其他回答

在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

编辑:添加了Python 3的示例代码

注意:另一个答案看起来提供了一个更完整的实现,类似于下面(具有更多的功能)。

首先,创建一个元类:

class MetaConst(type):
    def __getattr__(cls, key):
        return cls[key]

    def __setattr__(cls, key, value):
        raise TypeError

这可以防止静态属性被更改。然后创建另一个使用该元类的类:

class Const(object):
    __metaclass__ = MetaConst

    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        raise TypeError

或者,如果你使用的是python3:

class Const(object, metaclass=MetaConst):
    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        raise TypeError

这应该可以防止实例道具被更改。要使用它,继承:

class MyConst(Const):
    A = 1
    B = 2

现在,直接或通过实例访问的props应该是常量:

MyConst.A
# 1
my_const = MyConst()
my_const.A
# 1

MyConst.A = 'changed'
# TypeError
my_const.A = 'changed'
# TypeError

下面是上面的一个例子。下面是Python 3的另一个例子。

元组在技术上属于常量,因为如果您试图更改其中一个值,元组将引发错误。如果你想声明一个只有一个值的元组,那么在它唯一的值后面加一个逗号,就像这样:

my_tuple = (0 """Or any other value""",)

要检查这个变量的值,使用类似这样的方法:

if my_tuple[0] == 0:
    #Code goes here

如果您试图更改此值,将引发一个错误。

你可以通过collections.namedtuple和itertools来实现:

import collections
import itertools
def Constants(Name, *Args, **Kwargs):
  t = collections.namedtuple(Name, itertools.chain(Args, Kwargs.keys()))
  return t(*itertools.chain(Args, Kwargs.values()))

>>> myConstants = Constants('MyConstants', 'One', 'Two', Three = 'Four')
>>> print myConstants.One
One
>>> print myConstants.Two
Two
>>> print myConstants.Three
Four
>>> myConstants.One = 'Two'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

您可以在下一个类的帮助下模拟常量变量。用法示例:

# Const
const = Const().add(two=2, three=3)

print 'const.two: ', const.two
print 'const.three: ', const.three

const.add(four=4)

print 'const.four: ', const.four

#const.four = 5 # a error here: four is a constant

const.add(six=6)

print 'const.six: ', const.six

const2 = Const().add(five=5) # creating a new namespace with Const()
print 'const2.five: ', const2.five
#print 'const2.four: ', const2.four # a error here: four does not exist in const2 namespace

const2.add(five=26)

当您希望启动一个新的常量名称空间时,请调用构造函数。注意,当Martelli的const类没有被修改时,这个类受到了保护,不受意外修改序列类型常量的影响。

来源如下。

from copy import copy

class Const(object):
"A class to create objects with constant fields."

def __init__(self):
    object.__setattr__(self, '_names', [])


def add(self, **nameVals):
    for name, val in nameVals.iteritems():          
        if hasattr(self, name):
            raise ConstError('A field with a name \'%s\' is already exist in Const class.' % name)

        setattr(self, name, copy(val)) # set up getter

        self._names.append(name)

    return self


def __setattr__(self, name, val):
    if name in self._names:
        raise ConstError('You cannot change a value of a stored constant.')

    object.__setattr__(self, name, val)