【python小课堂专栏】python小课堂36 - 你可知对象也有真假之分?

python小课堂36 - 你可知对象也有真假之分?

前言

前天写了一篇《零基础如何入门Python》,感兴趣的读者可以看一下。学习多数靠自律,毕竟在编程领域,勤真的能补拙。。。

今天这篇标题有人可能会疑惑,大概看不明白是什么意思吧…来解释一下,Python 中一切万物皆为对象,而几乎所有的对象都是和 Python 中 True 和 False 有着对应关系的。下面就来看下怎么回事!~

PS:本章会带你一步步有逻辑性的进行推理,耐心观看!

Python各种对象的真与假

《小课堂Python35》中,提到了一个 None的关键词,在 Python 中代表空的意思。在初期的时候,介绍过 bool() 的用法,它是 Python 的内置函数,使用它可以判断对象的结果是 True 还是 False。如下:

在这里插入图片描述

结果显示:None 的布尔类型为 False。

为了提起回忆,再来几个,分别字符串、数字、列表的空与不空。

除了数字型特殊,不难观察到,只有0才是False,剩下的数字都是True。而字符串和列表,但凡是空值,则是False。

在这里插入图片描述

由以上观察结果,得出一个结论1:但凡是一个空值的对象(不包括数字),那么它的布尔类型一定是False。

上面的结论是否真的正确?看到这里思考质疑一下,真的是对的吗?

反驳上面的结论示例如下:

如果由我们来自定义一个空壳对象,并且将对象进行实例化,判断实例化后的布尔值,你觉得会得到怎样的结果呢?

业务场景:

手写一个名为 TestBool 的类,当然这个类里什么也不写,目的就是为了让它看起来是空的,然后对这个类进行实例化,最后打印实例化的布尔值。可以思考下,动手实验后再看笔者答案。


class TestBool(object):
    pass

test = TestBool()
if test:
    print('Wow,test is True!')

print(f'验证是否真的是真:{bool(test)}')

在这里插入图片描述

结论2:由我们自身定义的一个空对象,将它实例化,得到的结果却是 True,反驳了上面的结论!虽然看上去为空对象,但若是使用type()查看下就知道,它的类型并不是 None,而是自己定义的类型,可以理解为对象已经存在,所以它依然会走进 if 的分支中去。

多说一句,对象存在的理解。

举个例子,有对夫妻要生孩子。

如果已经生下来了,取名字叫“小明”,“小明”目前是真实存在这个世上,那就是实例化出来的 test 。

实例化出来的就已经是实体了,这个实体会占用内存的,并且是一个对象的形式存在。

对象真假值背后的原理

既然对象根据不同的应用场景会出现“真假”,那么它背后的原理究竟是什么呢?是什么左右了它的布尔值呢?

将自定义对象中添加一个内置方法 len(self),并返回0。

PS:内置方法之前在面向对象中简单的介绍过,python小课堂19 - 面向对象篇(二)。

class TestBool(object):
    def __len__(self):
        return 0

test = TestBool()
if test:
    print('Wow,test is True!')
else:
    print('False.....!!')

print(f'验证是否真的是真:{bool(test)}')

在这里插入图片描述

神奇的事情发生了,自定义对象,通过内置方法 len 改变了自身的布尔类型,只因为返回了0,这便是其中的原理!

好奇宝宝1号总会多试探下,若不返回0,我返回其他数字行吗?行啊没问题,代码如下:


class TestBool(object):
    def __len__(self):
        return 10
        
test = TestBool()

if test:
    print('Wow,test is True!')
else:
    print('False.....!!')

print(f'验证是否真的是真:{bool(test)}')
print(f'长度:{len(test)}')

在这里插入图片描述

可以看到,改为10后,不光对象的布尔类型又回到了True,而且笔者还将它的长度打印出来!勤于思考的同学一定会想到,内置方法__len__ 和 len() 单词语法长这么像,一定会关联!

没错,内置方法__len__ 决定着对象的 len() 长度,而同时 len 的返回值也控制着一个对象的真与假!返回0就是假,其余数字都是真!

好奇宝宝2号也想多试探下,不返回数字行吗?返回个空列表,空字符是不是可以影响对象的布尔类型为 False?

在这里插入图片描述

好奇宝宝2失败,对于 len 来说只能返回整形数字,那么话又说回来了,其实还可以直接返回 True 或者 False,因为他们对应着数字呀:

在这里插入图片描述

所以可以尝试,当返回 False 时的结果:

在这里插入图片描述

需要注意一点,对象中若是没有定义内置函数 len ,直接调用 len() 是会报错的,也就是说 len() 的内置原理其实就是对象的内置方法 len ,如下图:

在这里插入图片描述

结论3:结论1和结论2都不是最终的答案,在 Python 中,若是自定义对象,需要看对象中的 len 返回结果,才能判断一个对象的布尔类型。

那么问题又来了!我们都知道有个 bool() 的方法可以看一个对象的布尔值,好奇宝宝3号会不会好奇,其实它的内置原理是有个叫 bool 的内置函数在起着作用呢?

没错,好奇宝宝3号想的太TM对了…代码如下:


class TestBool(object):

    def __bool__(self):
        print('__bool__ is execute')
        return True

    def __len__(self):
        print('__len__ is execute')
        return 0

test = TestBool()
if test:
    print('Wow,test is True!')
else:
    print('False.....!!')

print(f'验证是否真的是真:{bool(test)}')

在这里插入图片描述

lenbool 同时存在时,可以看到上面代码结果,bool 起着效果,因为它返回的是 True,而 len 返回的是0,按理应该返回 False,然而它并没有生效。

意味着,boollen 同时存在,判断对象的布尔值时,“正宫”是 boollen 会失效!bool 返回的类型只能是布尔类型,即 True 或者 False,有兴趣的可以自行尝试。

终极结论: 通过结论 1~3,得出一个终极 boss 结论。对于Python的普通类型来说,空值是 False的;对于自定义对象来说,先看内置方法 __bool__的返回结果,若有则以此为准,若无则以 len 返回的结果为准。若既没有 bool ,也没有 len 方法,默认布尔值结果返回为 True。

总结

本篇文章从0到1,以有序的逻辑推理了一遍,相信看到最后的你一定会有所收获,因为在正常的编程中,很多情况下是对 对象 是否为空的 if 判断,若基础概念模糊,会导致一些想象不到的 bug 产生!关于结论,记住最后的终极结论即可。


文章首发公众号,欢迎关注: **migezatan.(咪哥杂谈)**
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页