鱼C论坛

 找回密码
 立即注册
查看: 1835|回复: 4

[已解决]关于__bool__方法的代偿

[复制链接]
发表于 2023-6-22 22:40:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
学习不同方法的代偿时,碰到的问题也不一样,各位老师都给了非常大的帮助,非常感谢, 请看看下面的问题:
>>> class D:
        def __bool__(self):
                print('Bool')
                return True

        
>>> d = D()
>>> bool(d)
Bool
True

上面的代码是正常的代码,定义了__bool__方法,无论何种情况,都会返回True


>>> class D:
        def __init__(self, data):
                self.data = data
        def __len__(self):
                print('len:', len(self.data))
                return len(self.data)

        
>>> d = D('cat')
>>> bool(d)
len: 3
True
上面的代码是用 __len__方法代偿的代码,让我不理解的是,办法中的 return 返回的是len(self.data),应该是3啊,为什么返回结果是True呢? 是不是还有什么函数悄悄在起作用啊?

最佳答案
2023-6-23 10:55:04
wbzxz 发表于 2023-6-23 07:09
@sfqxx  @isdkz

非常感谢老师的指点, 但是我始终没有理解一个问题。

在Python中,所有对象都可以被看作是真值或假值。当执行布尔运算如`bool(a)`时,Python将调用其相应的魔术方法(`__bool__`, `__len__`, `__nonzero__`)之一(按优先级顺序)。只要其中一个方法返回了True或者非零整数,则该对象就被视为真值;否则,它被视为假值。

因此,在你引入的例子中,类`D`没有实现`__bool__`方法,但是实现了`__len__`方法,所以在计算布尔值时,Python会尝试调用`__len__`方法并通过检查返回值是否为零来确定该对象的布尔值。如果该对象存在且其长度不为零,则返回True,否则返回False。

所以在你的例子中,调用`bool(d)`会首先尝试调用`d.__bool__()` 方法,但是由于该方法不存在,Python会自动调用`d.__len__()`方法,它打印出了长度并返回了非零的长度值3,这就是为什么可以打印 "len: 3" 而返回True的原因。

求最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-6-22 22:46:38 | 显示全部楼层
在上面的代码中,我们定义了一个类D,并实现了它的 __len__ 方法。当我们调用 bool(d) 时,Python会尝试调用 d.__bool__() ,如果 __bool__ 方法不存在,则会调用 d.__len__() 方法。

在代码中,我们没有定义 __bool__ 方法,但是我们定义了 __len__ 方法。当我们调用 bool(d) 时,Python会自动调用 d.__bool__() 方法,但是这个方法并不存在,因此Python会尝试调用 d.__len__() 方法来获取一个非零的返回值。
在 __len__ 方法中,我们打印了长度,并且返回了长度 3 。根据Python的规定,长度为0的对象在布尔上下文中被视为False,非零长度的对象被视为True。
所以,最终的返回结果是True,因为字符串 'cat' 的长度为3,不为0。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-22 22:47:30 | 显示全部楼层
在第二段代码中,bool(d) 调用了对象 d 的 __bool__ 方法来确定其布尔值。但是在类 D 中,并没有定义 __bool__ 方法。

根据 Python 语言的规则,如果一个对象没有定义 __bool__ 方法,Python 会尝试使用其他方法来确定其布尔值。其中一种方法是尝试调用对象的 __len__ 方法来确定布尔值。

所以,在类 D 中,当我们调用 bool(d) 时,Python 会尝试调用对象 d 的 __len__ 方法来确定其布尔值。

在类 D 中,我们定义了 __len__ 方法,它返回了 self.data 的长度。因此,在调用 bool(d) 时,会先调用 __len__ 方法并打印长度为 3,然后根据 __len__ 方法的返回值来确定布尔值。

由于返回的长度不为 0,所以布尔值为 True。因此,bool(d) 返回的结果是 True。

求最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-23 07:09:58 | 显示全部楼层
@sfqxx  @isdkz

非常感谢老师的指点, 但是我始终没有理解一个问题。

既然没有找到 __bool__ 方法,找到了  __len__   方法,那就是用 __len__ 方法代偿,就会执行  __len__ 方法 中的语句,但是代码中  __len__ 方法只是返回了长度值(return len(self.data)) , 根本没有进行布尔值判断的语句啊,为什么能返回布尔值呢(没有了bool方法,就不会出现布尔值啊)?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-23 10:55:04 | 显示全部楼层    本楼为最佳答案   
wbzxz 发表于 2023-6-23 07:09
@sfqxx  @isdkz

非常感谢老师的指点, 但是我始终没有理解一个问题。

在Python中,所有对象都可以被看作是真值或假值。当执行布尔运算如`bool(a)`时,Python将调用其相应的魔术方法(`__bool__`, `__len__`, `__nonzero__`)之一(按优先级顺序)。只要其中一个方法返回了True或者非零整数,则该对象就被视为真值;否则,它被视为假值。

因此,在你引入的例子中,类`D`没有实现`__bool__`方法,但是实现了`__len__`方法,所以在计算布尔值时,Python会尝试调用`__len__`方法并通过检查返回值是否为零来确定该对象的布尔值。如果该对象存在且其长度不为零,则返回True,否则返回False。

所以在你的例子中,调用`bool(d)`会首先尝试调用`d.__bool__()` 方法,但是由于该方法不存在,Python会自动调用`d.__len__()`方法,它打印出了长度并返回了非零的长度值3,这就是为什么可以打印 "len: 3" 而返回True的原因。

求最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-22 17:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表