由于python语言的简洁性,在判断一个容器是否为空的时候,比如列表,可以直接用if + 要判断的东西:

a = list()
if a:
    print('不为空')
else:
    print('列表为空')

如果是空会返回false,在有值的时候会返回true。

python fastapi 过一段时间就要重启不然手机连不上_自定义方法

这是因为列表加在 if 后面构成判断语句时,python是能判断要做什么,针对空列表,以及列表本身为none都hi返回false。

而如果是dataframe的话,就会报错了:

def get_df(df=None):
    res = df if df else pd.DataFrame() 
    print(res)


get_df(df)

python fastapi 过一段时间就要重启不然手机连不上_python_02

看到这个报错有点蒙,分析下,我这里是把df作为一个参数传进来,而我想要的逻辑是如果df传入就采用传入的值,没有传的话就新建(这里只是为了说明问题)。但是这样写会报错,从报错信息来看,也就是python认为它不清楚我想要让它判断什么,它不清楚什么是我想要的真,什么是假。

根据它的提示,如果我要判断这个数据框是否是一个空的数据框,我应该用empty,判断布尔值,应该用bool。。。等等。所以这里应该明确告诉python我的意图,我只是想知道有没有这个参数。所以进行以下改造:

def get_df(df=None):
    res = df if df is not None else pd.DataFrame()
    print(res)


get_df(df)

python fastapi 过一段时间就要重启不然手机连不上_简洁性_03

明确指定要判断的事情就可以了。从这里我也发现,数据框和传统的容器是有一些不同的,套用传统的操作时,还是要多加注意。


后续研究结果:

python的if是在调用内置方法 __bool__(),并且优先使用它,如果没有布尔方法则去找 __len__()方法。

举个例子:

python fastapi 过一段时间就要重启不然手机连不上_python_04

自定义一个类,定义__bool__方法和__len__方法。

实例化该类,并直接进行 if 判断该实例,它调用的实际是bool方法,结果为bool方法的返回值,false。

python fastapi 过一段时间就要重启不然手机连不上_自定义方法_05

注释掉 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__
            )
        )