《Python面向对象编程指南》——1.9 不带__init__()方法的无状态对象

1.9 不带__init__()方法的无状态对象

以下是一个不需要__init__()方法的类定义。对于策略模式的对象来说这是常见的设计。一个策略对象以插件的形式复合在主对象上来完成一种算法或逻辑。它或许依赖主对象中的数据,策略对象自身并不携带任何数据。通常策略类会和享元设计模式一起使用:在策略对象中避免内部存储。所有需要的值都从策略对象的方法参数传入。策略对象自身是无状态的,可以把它看作是一系列函数的集合。

这里定义了一个类给Player实例提供游戏模式的选择,以下这个策略包括了拿牌和下调投注。

class GameStrategy:
   def insurance( self, hand ):
     return False
   def split( self, hand ):
     return False
   def double( self, hand ):
     return False
   def hit( self, hand ):
     return sum(c.hard for c in hand.cards) <= 17

每个函数需要传入已有的Hand对象。函数逻辑所需的数据基于现有的可用信息,意味着数据会来自庄家和玩家手中的牌。

我们可以创建一个单例的策略对象给多个玩家实例来调用。

dumb = GameStrategy()

我们也可以根据 21 点给玩家提供的不同玩法,考虑定义一系列像这样的策略对象。

时间: 2024-12-23 13:55:16

《Python面向对象编程指南》——1.9 不带__init__()方法的无状态对象的相关文章

《Python面向对象编程指南》——2.8 __new__()方法和不可变对象

2.8 __new__()方法和不可变对象 __new__方法的一个用途是初始化不可变对象.__new__()方法中允许创建未初始化的对象.这允许我们在__init__()方法被调用之前先设置对象的属性. 由于不可变类的__init__()方法很难重载,因此__new__方法提供了一种扩展这种类的方法. 下面是一个错误定义的类,我们定义了float的一个包含单位信息的版本. class Float_Fail( float ): def __init__( self, value, unit ):

《Python面向对象编程指南》——2.2 __format__()方法

2.2 __format__()方法 string.format()和内置的format()函数都使用了__format__()方法.它们都是为了获得给定对象的一个符合要求的字符串表示. 下面是给__format__()传参的两种方式. someobject.__format__(""):当应用程序中出现format(someobject)或者"{0}".format(someobject)时,会默认以这种方式调用__format__().在这些情况下,会传递一个空

《Python面向对象编程指南》——2.5 __bytes__()方法

2.5 __bytes__()方法 只有很少的情景需要我们把对象转换为字节.在第2部分"持久化和序列化"中,我们会详细探讨这个主题. 通常,应用程序会创建一个字符串,然后使用Python的IO类内置的编码方法将字符串转换为字节.对于大多数情况,这种方法就足够了.只有当我们自定义一种新的字符串时,我们会需要定义这个字符串的编码方法. 依据不同的参数,bytes()函数的行为也不同. bytes(integer):返回一个不可变的字节对象,这个对象包含了给定数量的0x00值. bytes(

《Python面向对象编程指南》——2.3 __hash__()方法

2.3 __hash__()方法 内置的hash( )函数默认调用了__hash__()方法.哈希是一种将相对复杂的值简化为小整数的计算方式.理论上说,一个哈希值可以表示出源值的所有位.还有一些其他的哈希方法,会得出非常大的值,这样的算法通常用于密码学. Python中有两个哈希库.其中,hashlib可以提供密码级别的哈希函数,zlib模块包含两个高效的哈希函数:adler32()和crc32().对于相对简单的值,我们不使用这些内置的函数,对于复杂的或者很大的值,这些内置的函数可以提供很大的

《Python面向对象编程指南》——2.7 __del__()方法

2.7 __del__()方法 __del__()方法有一个让人费解的使用场景. 这个方法的目的是在将一个对象从内存中清除之前,可以有机会做一些清理工作.如果使用上下文管理对象或者with语句来处理这种需求会更加清晰,这也是第5章"可调用对象和上下文的使用"的内容.对于Python的垃圾回收机制而言,创建一个上下文比使用__del__()更加容易预判. 但是,如果一个Python对象包含了一些操作系统的资源,__del__()方法是把资源从程序中释放的最后机会.例如,引用了一个打开的文

《Python面向对象编程指南》——2.9 new()方法和元类型

2.9 new()方法和元类型 __new__()方法的另一种用途,作为元类型的一部分,主要是为了控制如何创建一个类.这和之前的如何用__new__()控制一个不可变对象是完全不同的. 一个元类型创建一个类.一旦类对象被创建,我们就可以用这个类对象创建不同的实例.所有类的元类型都是type,type()函数被用来创建类对象. 另外,type()函数还可以被用作显示当前对象类型. 下面是一个很简单的例子,直接使用type()作为构造器创建了一个新的但是几乎完全没有任何用处的类: Useless=

《Python面向对象编程指南》——2.4 __bool__()方法

2.4 __bool__()方法 Python中有很多关于真假性的定义.参考手册中列举了许多和False等价的值,包括False.0.''.().[]和{}.其他大部分的对象都和True等价. 通常,我们会用下面的语句来测试一个对象是否"非空". if some_object: process( some_object ) 默认情况下,这个是内置的bool()函数的逻辑.这个函数依赖于一个给定对象的__bool__()方法. 默认的__bool__()方法返回True.我们可以通过下面

《Python面向对象编程指南》——导读

前 言 本书主要介绍Python语言的高级特性,特别是如何编写高质量的Python程序.这通常意味着编写高性能且拥有良好可维护性的程序.同时,我们也会探究不同的设计方案并确定究竟是哪种方案提供了最佳性能.而对于一些正在寻找解决方案的问题,这也是一种很好的方式. 本书的大部分内容将介绍一种给定设计的不同替代方案.一些方案性能更好,另一些方案更加简单或者更加适合于特定领域的问题.最重要的是,找到最好的算法和最优的数据结构,以最少的开销换取最大的价值.时间就是金钱,高效的程序会为它们的用户创造更多的价

《Python面向对象编程指南》——1.5 通过工厂函数调用__init()__

1.5 通过工厂函数调用__init()__ 我们可以使用工厂函数来完成所有Card对象的创建,这比枚举52张牌的方式好很多.在Python中,实现工厂有两种途径. 定义一个函数,返回不同类的对象. 定义一个类,包含了创建对象的方法.这是完整的工厂设计模式,正如设计模式书中提到的.在类似Java这样的语言里,工厂类层次结构是必需的,因为语言本身不支持可以脱离类而单独存在的函数. 在Python里,类定义不是必需的.仅当特别复杂的情形,工厂类才是不错的选择.Python的优势之一是,对于只需要简单