wbzxz 发表于 2023-6-22 22:40:25

关于__bool__方法的代偿

学习不同方法的代偿时,碰到的问题也不一样,各位老师都给了非常大的帮助,非常感谢, 请看看下面的问题:

>>> 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呢? 是不是还有什么函数悄悄在起作用啊?

isdkz 发表于 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。

sfqxx 发表于 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。

求最佳答案{:10_254:}

wbzxz 发表于 2023-6-23 07:09:58

@sfqxx@isdkz

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

既然没有找到 __bool__ 方法,找到了__len__   方法,那就是用 __len__ 方法代偿,就会执行__len__ 方法 中的语句,但是代码中__len__ 方法只是返回了长度值(return len(self.data)) , 根本没有进行布尔值判断的语句啊,为什么能返回布尔值呢(没有了bool方法,就不会出现布尔值啊)?

sfqxx 发表于 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的原因。

求最佳答案{:10_254:}
页: [1]
查看完整版本: 关于__bool__方法的代偿