首先,很抱歉我的英语不好。
最近我读了叶戈尔·布加延科的一本名为《优雅的物品》的书。本书中的一个主题是使用对象而不是公共常量。作者写道,公共常数是一种纯粹的邪恶。这有很多原因。例如,公共常量的使用打破了封装——如果我们想改变这个常量,我们需要知道包的类是如何使用这个常量的。若项目中的两个类以自己的方式使用这个常量,若我们更改常量,我们需要更改这两个类的代码。
作者建议,我们不需要使用全局常量来创建对象,这样我们就可以只在一个地方更改代码。我将在下面举一个例子。
我已经在stackoverflow上读过类似的主题,但没有找到关于最佳实践或用例的答案。使用对象是否比在某些文件(例如"settings.py")中创建全局变量更好?
这是吗
class WWStartDate:
date_as_string = '01.09.1939'
def as_timestamp(self):
# returns date as timestamp
def as_date_time(self):
# returns date as datetime object
比这个存储在包conf.py内的一些文件中更好,例如:
DATE_STRING = '01.09.1939'
如果我们正在讨论在包的几个类中使用此日期?
读完这本书后,我认为对象要好得多,但我看到了很多框架或库的开发人员强迫我们使用全局变量的情况。所以这并不像我所看到的那么简单。例如,django为什么使用这种方法?我说的是文件设置.py.
我认为,为常量创建一个类,以不同的形式提供给不同的(其他)类,这是在过度设计常量。为什么常数必须知道它是如何使用的?math.pi
知道它是如何使用的吗?它实际上有一些方法,因为它是一个float
对象。没有特定于pi常数的内容。此外,当您这样做时,您将常量与其他类耦合,当它们更改用途时,您可能必须更新常量类。现在这是个坏主意。你希望它们解耦。每个类(并且只有这个类)应该知道它对常量做了什么。
这并不是说包装类有时不会有用,特别是当您对相关常量进行分组时。但他们也可以使用Enum
。
一个模块中的全局变量只是该模块中的局部变量。导入时,您使用的是副本或(限定的)链接名称。但是,即使在链接的情况下,如果您使用限定更改导入的值(因为您说它是常量,所以不应该更改),并且另一个模块正在导入相同的值,它也看不到您所做的更改。它们使用不同的名称空间。当我们说全局变量是邪恶的时,这不是通常的"全局变量"概念。