********************************************************************
*****摘自<编写高质量代码 改善Python程序的91个建议>*****
********************************************************************
在学习Python的过程中,是否写过如下代码来判断变量a是否为空:
1 if a is not None: # value is not empty 2 Do Something 3 4 else: # value is empty 5 Do Some other thing
那么这样写有什么问题吗?
先了解一下Python中哪些形式的数据为空。
- 常量None
- 常量False
- 任何形式的数值类型零,如0、0L、0.0、0j
- 空的序列,如""、[]、()
- 空的字典,如{}
- 当用户定义的类中定义了__nonzero__()方法和__len__()方法,并且该方法返回整数0或者布尔值False的时候
其中,常量None的特殊性体现在它既不是0、False,也不是空字符串,它就是一个空值对象。其数据类型为NoneType,遵循单例模式,是唯一的,因此不能创建None对象。所有赋值为None的变量都相等,并且None与任务其他非None的对象比较结果都为Flase。
1 >>> id(None) 2 10302688 3 >>> None == 0 # None不为0 4 False 5 >>> None == False # None也不是False 6 False 7 >>> None == "" # None更不是空字符串 8 False 9 >>> a = None 10 >>> id(a) 11 10302688 12 >>> b = None 13 >>> id(b) 14 10302688 15 >>> a == b # 任何赋值为None的对象都相同 16 True 17 >>> list1 = [] 18 >>> if list1 is not None: 19 ... print("list is: %s" % list1) 20 ... else: 21 ... print("list is empty") 22 ... 23 list is: [] 24 >>>
上面的例子中,对列表是否为空的判断显然不符合我们的要求,因为除非a被赋值为None,否则else中的语句永远不会被执行。正确的形式如下:
1 >>> if list1: # value is not empyt, 判定list1是否为空的正确方式 2 ... print("list is:{0}".format(list1)) 3 ... else: # value is empty 4 ... print("list is empty") 5 ... 6 list is empty 7 >>>
if list1执行时会调用内部方法__nonzero__()来判定变量list1是否为空并返回其结果。
__nonzero__():该内部方法用于对自身对象进行空值测试,返回0/1或True/False。如果一个对象没有定义该方法,则获取__len__()的返回结果来进行判断;
__len__():该内部方法的返回值为0则表示为空;
如果一个对象既没有定义__nonzero__()方法,也没有定义__len__()方法,该类的实例用if判定的结果都为True