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

2.4 __bool__()方法

Python中有很多关于真假性的定义。参考手册中列举了许多和False等价的值,包括False、0、''、()、[]和{}。其他大部分的对象都和True等价。

通常,我们会用下面的语句来测试一个对象是否“非空”。

if some_object:
   process( some_object )

默认情况下,这个是内置的bool()函数的逻辑。这个函数依赖于一个给定对象的__bool__()方法。

默认的__bool__()方法返回True。我们可以通过下面的代码来验证这一点。

>>> x = object()
>>>bool(x)
True

对大多数类来说,这是完全正确的。大多数对象都不应该和False等价。但是,对于集合,这样的行为并不总是正确的。一个空集合应该和False等价,而一个非空集合应该返回True。或许,应该给我们的Deck集合对象增加一个类似的方法。

如果我们在封装一个列表,我们可能会写下面这样的代码。

def __bool__( self ):
   return bool( self._cards )

这段代码将__bool__()的计算委托给了内部的集合_cards。

如果我们在扩展一个列表,可能会写下面这样的代码:

def __bool__( self ):
   return super().__bool__( self )

这段代码使用了基类中定义的__bool__()函数。

在这两个例子中,我们都将布尔值的计算委托给其他对象。在封装的例子中,我们委托给了一个内部的集合。在扩展的例子中,我们委托给了基类。不管是封装还是扩展,一个空集合的布尔值都是False。这会让我们很清楚Deck对象是否已经被处理完了。

现在,我们就可以像下面这样使用Deck。

d = Deck()
while d:
   card= d.pop()
   # process the card

这段代码会处理完Deck中所有的牌,当所有的牌都处理完时,也不会抛出IndexError异常。

时间: 2024-07-30 15:03:04

《Python面向对象编程指南》——2.4 __bool__()方法的相关文章

《Python面向对象编程指南》——第1部分 用特殊方法实现Python风格的类 第1章 __init__()方法 1.1 隐式的基类——object

第1部分 用特殊方法实现Python风格的类 init()方法 与Python无缝集成--基本特殊方法 属性访问.特性和修饰符 抽象基类设计的一致性 可调用对象和上下文的使用 创建容器和集合 创建数值类型 装饰器和Mixins--横切方面 用特殊方法实现 Python风格的类 通过重写特殊方法来完成对Python内部机制的调用,在Python中是很普遍的.例如len()函数就可以重写一个类的__len__()方法. 这意味着对于像(len(x))这样的通用公共接口,任何类(例如,声明一个类叫ti

《Python面向对象编程指南》——2.6 比较运算符方法

2.6 比较运算符方法 Python有6个比较运算符.这些运算符分别对应一个特殊方法的实现.根据文档,运算符和特殊方法的对应关系如下所示. x < y调用x.__lt__(y). x <=y调用x.__le__(y). x == y调用x.__eq__(y). x != y调用x.__ne__(y). x > y调用x.__gt__(y). x >= y调用x.__ge__(y). 我们会在第7章"创建数值类型"中再探讨比较运算符. 对于实际上使用了哪个比较运算

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

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

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

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

《Python面向对象编程指南》——2.10 总结

2.10 总结 我们已经介绍了许多基本的特殊方法,它们是我们在设计任何类时的基本特性.这些方法已经包含在每个类中,只是它们的默认行为不一定能满足我们的需求. 我们几乎总是需要重载__repr__().__str__().和__format__().这些方法的默认实现不是非常有用. 我们几乎不需要重载__bool__()方法,除非我们想自定义集合.这是第6章"创建容器和集合"的主题. 我们常常需要重载比较运算符和__hash__()方法.默认的实现只适合于比较简单不可变对象,但是不适用于

《Python面向对象编程指南》——第2章 与Python无缝集成——基本特殊方法 2.1 __repr__()和__str__()方法

第2章 与Python无缝集成--基本特殊方法 Python中有一些特殊方法,它们允许我们的类和Python更好地集成.在标准库参考(Standard Library Reference)中,它们被称为基本特殊方法,是与Python的其他特性无缝集成的基础. 例如,我们用字符串来表示一个对象的值.Object基类包含了__repr__()和__str__()的默认实现,它们提供了一个对象的字符串描述.遗憾的是,这些默认的实现不够详细.我们几乎总会想重写它们中的一个或两个.我们还会介绍__form

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

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

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

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

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

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