概述
python判断一个对象是否为空我们可以很方便地使用 if 对象
,这次碰到的异常让我需要重新思考这个方式的适用性。
异常回顾
# 用get方法从字典中拿值
if dict.get("qh"):
pass
结果直接报错如下
image.png
原因
从dict中get到的有俩种情况,一是为空,二是为一个pandas.DataFrame
,第一种情况if是适用的,但是对于非python预设对象DataFrame,if就出了问题。原因分析如下:
python的if是在调用内置方法 bool(),并且优先使用它,如果没有布尔方法则去找 len()方法。
举个例子:
image
自定义一个类,定义bool方法和len方法。
实例化该类,并直接进行 if 判断该实例,它调用的实际是bool方法,结果为bool方法的返回值,false。
image
注释掉 bool 方法,可以看到它调用的是 len 方法,len 返回为1,只有0 为false,其他都是true,所以返回true。
由此可以得知,如果想让 if 逻辑判断自己定义的逻辑,需要定义bool方法,某种情况下 len也可以。
上述报错是因为dataframe继承自ndframe,而ndframe重写了bool()方法,将其指向为自定义方法:__nonzero__()。
__bool__ = __nonzero__
在这个自定义方法里,什么都没有做,只是抛了一个异常:
def __nonzero__(self): raise ValueError( "The truth value of a {0} is ambiguous. " "Use a.empty, >a.bool(), a.item(), a.any() or a.all().".format( self.__class__.__name__))
目的,应该是为了避免直接使用 if df的写法。
解决方法
首先需要注意get到的对象的类型,使用那种类型的判空方法,而不是无脑if。对于DataFrame,判空方法为DataFrame.empty,没有括号。
其次,get不一定会返回DataFrame,做一个兼容即可:
if dict.get('qh',pandas.DataFrame()).empty