就 PEP8 命名风格而言,什么时候变量被认为是常量?

When is a variable considered constant in terms of PEP8 naming styles?

为了与 PEP8 约定保持一致,在 .py 中我可以将常量定义为:

NAME = "Me"
AGE = "Old"
GENER = "Male"

如果 .txt 在一行中包含 Me Old Male,而在另一行 .py 中我执行了:

FILE = "C:/path/to/file.txt"  # a declared constant, easy
with open(FILE, 'r') as f:
    content = f.read().rstrip('\n').split()
    data = ','.join(content)  # returns Me,Old,Male

问题:

contentdata 可以被认为是常量吗?

要成为常量,是否必须在构建时将变量声明为常量?

或者常量副变量是运行时用户输入改变能力的函数吗?

支持信息:

content 是文件中的内容,但它受制于 .rstrip().split() 但它作为一个整体以后永远不会更改。 datacontent 制成,没有改变也不会改变,并受 .join() 约束。两个值在初始化后都不会改变。

我认为这类似于:

>>> A = 2  # a declared constant
>>> B = 2  # another declared constant
>>> TOTAL = A + B  # 'caps' per PEP8 for constant naming
4

假设程序已经终止并且 TOTAL 永远不会改变,我会认为这个值是一个常数。再次假设任何在运行时不可更改的变量都被视为常量。

请根据需要随意更改我的概念以符合标准!

如果您要在其余代码中将该值视为常量,请务必对这些全局变量使用 CONSTANT_CASE。这取决于你,它只是一个文档约定。

换句话说,这是一个约定,旨在让未来的代码读者更容易理解这样一个全局变量的值只设置一次并且是预期的在程序的生命周期内不要更改。

请注意,我通常会尽量避免在模块导入时加载文件数据;它使测试变得更加困难并影响性能。而是在第一次使用时加载该数据(使用函数)。

我认为您将常量变量的概念与文件中保存的实际数据混为一谈。 Python 并没有真正像 C 或 Java 那样的常量概念。因此,用大写变量名声明常量变量的符号只是告诉程序员(你)你正在处理一个不应该改变的变量的约定,但是 python 不会限制你这样做。

对于"real"常量,我能想到的唯一方法是使它成为class中的一个属性,并限制__setattr__:

class Constant:
    def __init__(self, name, age, gender):
        self.__dict__["NAME"] = name
        self.__dict__["AGE"] = age
        self.__dict__["Gender"] = gender

    def __setattr__(self, a, v):
        raise TypeError("Cannot set attributes of '{}' class".format(str(self.__class__).rsplit('.',1)[1]))

因此,您可以读取属性,但无法设置它们:

In [131]: c = Constant("Me", "Old", "Male")

In [132]: c.NAME
Out[132]: 'Me'

In [133]: c.NAME = 'd'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-133-d979661dfd1d> in <module>()
----> 1 c.NAME = 'd'

<ipython-input-130-9a8604514ac4> in __setattr__(self, a, v)
      6 
      7     def __setattr__(self, a, v):
----> 8         raise TypeError("Cannot set attributes of '{}' class".format(str(self.__class__).rsplit('.',1)[1]))

TypeError: Cannot set attributes of 'Constant'>' class