diff --git "a/src/20.Python\347\232\204\345\270\203\345\260\224\345\200\274\346\230\257\346\200\216\344\271\210\345\256\236\347\216\260\347\232\204\357\274\214\344\275\240\345\257\271\345\256\203\347\232\204\344\272\206\350\247\243\346\234\211\345\244\232\346\267\261\345\221\242\357\274\237.md" "b/src/20.Python\347\232\204\345\270\203\345\260\224\345\200\274\346\230\257\346\200\216\344\271\210\345\256\236\347\216\260\347\232\204\357\274\214\344\275\240\345\257\271\345\256\203\347\232\204\344\272\206\350\247\243\346\234\211\345\244\232\346\267\261\345\221\242\357\274\237.md" index d34ce8f..eb88ee4 100644 --- "a/src/20.Python\347\232\204\345\270\203\345\260\224\345\200\274\346\230\257\346\200\216\344\271\210\345\256\236\347\216\260\347\232\204\357\274\214\344\275\240\345\257\271\345\256\203\347\232\204\344\272\206\350\247\243\346\234\211\345\244\232\346\267\261\345\221\242\357\274\237.md" +++ "b/src/20.Python\347\232\204\345\270\203\345\260\224\345\200\274\346\230\257\346\200\216\344\271\210\345\256\236\347\216\260\347\232\204\357\274\214\344\275\240\345\257\271\345\256\203\347\232\204\344\272\206\350\247\243\346\234\211\345\244\232\346\267\261\345\221\242\357\274\237.md" @@ -12,14 +12,14 @@ print(bool.__base__) # print(isinstance(True, bool)) # True -# True 和 False 可以当成 1利 0 来用 +# True 和 False 可以当成 1 和 0 来用 print(True * 2) # 2 print(3 // 3 == True) # True print(sum([True, 1, 2])) # 4 print(False + 1) # 1 ~~~ -bool 在底层对应 PyBooL_Type,因此我们可以肯定地讲,PyBool_Type 的 tp_base 字段的值一定是 &PyLong_Type。 +bool 在底层对应 PyBool_Type,因此我们可以肯定地讲,PyBool_Type 的 tp_base 字段的值一定是 &PyLong_Type。 ~~~c // Objects/boolobject.c @@ -45,7 +45,7 @@ bool 继承 int,所以它也实现了 tp_as_number。 ## 布尔值的底层结构 -然后是 True 和 False,既然 bool 继承 int,那么布尔值和整数的底层结构是一样的。 +既然 bool 继承 int,那么布尔值和整数的底层结构是一样的。 ~~~C // Objects/boolobject.c @@ -152,16 +152,16 @@ PyObject_IsTrue(PyObject *v) // 如果 v 是 None,那么返回 0 if (v == Py_None) return 0; - // 如果 v 是数值型对象,并且它的类型对象定义了__bool__,那么调用 + // 如果 v 是数值型对象,并且它的类型对象定义了 __bool__,那么调用 else if (v->ob_type->tp_as_number != NULL && v->ob_type->tp_as_number->nb_bool != NULL) res = (*v->ob_type->tp_as_number->nb_bool)(v); // 如果 v 是映射型对象,并且它的类型对象定义了 __len__,那么调用 - // 说白了就是基于内部键值对的个数进行判断 + // 说白了就是基于内部的键值对个数进行判断 else if (v->ob_type->tp_as_mapping != NULL && v->ob_type->tp_as_mapping->mp_length != NULL) res = (*v->ob_type->tp_as_mapping->mp_length)(v); - // 如果 v 是序列型对象,并且它的类型对象定义了__len__,那么调用 + // 如果 v 是序列型对象,并且它的类型对象定义了 __len__,那么调用 // 也就是基于内部的元素个数进行判断 else if (v->ob_type->tp_as_sequence != NULL && v->ob_type->tp_as_sequence->sq_length != NULL) @@ -180,7 +180,7 @@ PyObject_IsTrue(PyObject *v) # 不传参数,默认返回 False print(bool()) # False -# 整数实现了__bool__,所以 bool(1) 会调用 int.__bool__(1) +# 整数实现了 __bool__,所以 bool(1) 会调用 int.__bool__(1) print(bool(1)) # True # 字符串实现了 __len__,所以 bool("abc") 会调用 str.__len__("abc") @@ -238,7 +238,7 @@ print(not not name) # True 而 not name 会对应一条 UNARY_NOT 字节码,它内部也会调用 PyObject_IsTrue,如果结果为 1 返回 False,为 0 返回 True,正好是相反的。所以 not not name 则相当于在 not name 的基础上再反过来一次,这样就和 bool(name) 的结果是一致的了。 -当然在工作中,无论使用哪种都可以,看自己喜好。但为了代码的可读性,显式获取布尔值的时候还是建议使用 bool(name),效率上没太大差别。 +当然在工作中,使用哪种都可以,看自己喜好。但为了代码的可读性,显式获取布尔值的时候还是建议使用 bool(name),效率上没太大差别。 ## 小结 @@ -246,8 +246,8 @@ print(not not name) # True + bool 继承 int,并且布尔值在底层和整数使用同一个结构体,只是 ob_type 不同; + 布尔值具备整数的所有特征,可以像整数一样参与各种运算,其中 True 会被解释成 1,False 会被解释成 0; -+ 布尔值有两种,分别是 True 和 False,它们是单例的。判断时应该使用 is,而不是 ==; -+ 在 Python 里面如果要创建布尔值,有三种方式:通过 True 和 False 字面量、调用类型对象 bool,使用 not not; ++ 布尔值有两种,分别是 True 和 False,它们是单例的,判断时应该使用 is,而不是 ==,除非你把 True 和 False 当成整数使用; ++ 在 Python 里面如果要创建布尔值,有三种方式:通过 True 和 False 字面量、调用类型对象 bool、使用 not not; -----