1.4 使用init()方法创建常量清单

    我们可以为所有卡片的花色单独创建一个类。可在21点应用中,花色不是很重要,用一个字母来代替就可以。

    这里使用花色的初始化作为创建常量对象的一个实例。很多情况下,应用会包括一个常量集合。静态常量也正构成了策略(Strategy)或状态(State)模式的一部分。

    有些情况下,常量会在应用或配置文件的初始化阶段被创建。或者创建变量的行为是基于命令行参数的。我们会在第16章“使用命令行”中介绍应用初始化和启动的详细设计过程。

    Python中并没有提供简单而直接的方式来定义一个不可变对象。我们会在第3章“属性访问、特性和修饰符”中介绍如何创建可靠的不可变对象。这个例子中,把花色这个属性定义为不可变是有意义的。

    如下代码定义了一个花色类,可以用来创建4个花色常量。

    class Suit:
      def init( self, name, symbol ):
        self.name= name
        self.symbol= symbol

    如下代码是对这个类的调用。

    Club, Diamond, Heart, Spade = Suit('Club','♣'), Suit('Diamond','♦'),
    Suit('Heart','♥'), Suit('Spade','♠')

    现在就可以使用如下代码创建Card对象了。

    cards = [ AceCard('A', Spade), NumberCard('2', Spade), NumberCard('3', Spade), ]

    对于以上的这个小例子来说,这样的方式相比于简单地使用一个字母来代替花色的实现方式并没有太大的优势。可在更复杂的情况下,可能会需要创建一组策略或状态模式对象的集合。如果把创建好的花色对象做缓存,构成一个常量池,使得在调用时对象可被重用,那么性能将得到显著的提升。

    我们不得不承认在Python中这些对象只是在概念上是常量,它们仍然是可变的。使用额外的代码实现使得这些对象成为完全不可变的可能会更好。

    无关紧要的不可变性 不可变性可能显得很有诱惑力。有时一些“恶意程序员”会修改应用程序中的常量。从设计的角度来看,这是愚蠢的,即使不可变变量也无法阻止这种恶意行为。没有任何简单的方法能够阻止这种恶意行为,程序员对代码进行恶意修改就像他们可以修改一个常量那样简单。 不再纠结于如何把类定义为不可变通常是更好的选择。在第3章“属性访问、特性和修饰符”中,我们会介绍不可变性的几种实现方法来为有bug的程序提供适当的诊断信息。