在Python函数中使用True,False和None作为返回值 - python

我认为我完全理解这一点,但我只是想确定一下,因为我一直看到人们说永远不要对TrueFalseNone进行测试。

他们建议例程应引发错误,而不是返回False或None。无论如何,在很多情况下,我只是想知道是否设置了标志,所以我的函数返回True或False。在其他情况下,如果没有有用的结果,我的函数将返回None。从我的想法来看,只要我意识到我永远都不要使用:

if foo == True
if foo == False
if foo == None

而是应使用:

if foo is True
if foo is False
if foo is None

因为True,False和None都是单例,并且在使用“ is”而不是“ ==”时将始终评估我期望的方式。我在这里错了吗?

同样,修改有时返回None的函数,而不是引发错误,是否更Pythonic?

说我有一个名为“ get_attr()”的实例方法,该方法从某些文件中检索属性。如果发现我请求的属性不存在,是否应该返回None?让他们提出一个错误并稍后发现它会更好吗?

参考方案

建议不是不要使用TrueFalseNone。只是您不应该使用if x == True

if x == True很愚蠢,因为==只是一个二进制运算符!它的返回值是TrueFalse,具体取决于其参数是否相等。如果if condition为true,则condition将继续。因此,当您编写if x == True时,Python将首先评估x == True,如果Truex则为True,否则为False,然后在结果为true时继续执行。但是,如果您期望xTrueFalse,为什么不直接使用if x

同样,x == False通常可以用not x代替。

在某些情况下,您可能想使用x == True。这是因为if语句条件是在布尔上下文中“求值”的,以查看其是否“真实”,而不是针对True进行精确测试。例如,if语句将非空字符串,列表和字典以及非零数值都视为真值,但都不等于True。因此,如果您要测试任意值是否恰好是True值,而不仅仅是使用if x == True时是否为真值。但是我几乎从来没有看到这种用法。非常罕见,如果您确实需要编写该注释,那么值得添加注释,以便将来的开发人员(包括您自己)不要仅仅认为== True是多余的并将其删除。

实际上,使用x is True更糟糕。绝对不能将is与基本的内置不可变类型(如布尔值(TrueFalse),数字和字符串)一起使用。原因是对于这些类型,我们关心的是价值,而不是身份。 ==测试这些类型的值是否相同,而is始终测试身份。

测试身份而不是值是不好的,因为实现理论上可以构造新的布尔值而不是查找现有的值,从而导致您拥有两个具有相同值的True值,但是它们存储在内存中的不同位置并且具有不同的值身份。实际上,我很确定TrueFalse总是被Python解释器重用,因此不会发生这种情况,但这实际上是实现细节。这个问题经常使人感到困惑,因为直接出现在程序源中的短字符串和文字字符串被Python回收,因此'foo' is 'foo'始终返回True。但是很容易以两种不同的方式构造相同的字符串,并让Python为它们提供不同的身份。请注意以下几点:

>>> stars1 = ''.join('*' for _ in xrange(100))
>>> stars2 = '*' * 100
>>> stars1 is stars2
False
>>> stars1 == stars2
True

编辑:因此,事实证明,Python对布尔值的相等性有点出乎意料(至少对我而言):

>>> True is 1
False
>>> True == 1
True
>>> True == 2
False
>>> False is 0
False
>>> False == 0
True
>>> False == 0.0
True

如the notes when bools were introduced in Python 2.3.5中所述,这样做的理由是使用整数1和0表示True和False的旧行为是好的,但是我们只想为打算表示真值的数字使用更多描述性名称。

实现该目标的一种方法是在内置的文件中简单地包含True = 1False = 0。那么1和True确实是无法区分的(包括is)。但这也意味着返回True的函数将在交互式解释器中显示1,因此要做的是将bool创建为int的子类型。 bool唯一不同的是strreprbool实例仍然具有与int实例相同的数据,并且仍然以相同的方式比较相等性,因此True == 1

因此,当某些代码期望x is True设置“ True只是拼写1的另一种方式”时,使用x是错误的,因为有很多方法可以构造等于True的值,但是不具有相同的身份:

>>> a = 1L
>>> b = 1L
>>> c = 1
>>> d = 1.0
>>> a == True, b == True, c == True, d == True
(True, True, True, True)
>>> a is b, a is c, a is d, c is d
(False, False, False, False)

x == True可以是任意Python值并且您只想知道它是否是布尔值x时,使用True是错误的。我们唯一可以确定的是,当您只想测试“真实性”时,最好使用x。值得庆幸的是,通常至少在我编写的代码中这就是全部!

更确定的方法是x == True and type(x) is bool。但是对于一个晦涩难懂的案例来说,这变得非常冗长。通过进行显式类型检查,它看起来也不是Python风格的……但是,这确实是您在尝试精确地测试True而不是真实情况时所做的事情。鸭子的输入方式是接受真实值,并允许任何用户定义的类将自己声明为真实。

如果您要处理非常精确的真理概念,那么您不仅不认为非空集合为真,而且不认为1为真,那么使用x is True可能就可以了,因为大概那么您知道x并非来自认为1为真的代码。我不认为有任何一种纯Python的方式可以提出另一个位于不同内存地址的True(尽管您可能可以从C实现),所以尽管从理论上讲这是“错误的, “ 要做的事。

我以前认为布尔值很简单!

结束编辑

但是,对于None,习惯用法是使用if x is None。在许多情况下,可以使用if not x,因为Noneif语句的“假”值。但是,最好仅在要以相同方式对待所有假值(零值数字类型,空集合和None)时执行此操作。如果要处理的值是其他可能的值或None表示“无值”(例如,函数失败时返回None),则最好使用if x is None不要偶然地假设函数刚巧返回一个空列表或数字0时就失败了。

对于不可变值类型使用==而不是is的论点表明,应该使用if x == None而不是if x is None。但是,在None的情况下,Python确实明确保证了整个宇宙中仅存在一个None,而常规的Python常规代码使用了is

关于返回None还是引发异常,取决于上下文。

对于类似您的get_attr示例的事情,我希望它会引发异常,因为我将像do_something_with(get_attr(file))这样称呼它。调用者的通常期望是,他们将获得属性值,并让他们获得None并假定该属性值是一个危险的危险,而不是如果您可以在属性可以继续的情况下实际上继续执行操作,则忘记忘记处理异常找不到。另外,返回None表示失败意味着None不是该属性的有效值。在某些情况下这可能是个问题。

对于像see_if_matching_file_exists这样的虚构函数,我们提供了一个模式,并检查几个位置以查看是否存在匹配项,如果找到一个匹配项,则它可能返回匹配项;如果找不到,则可能返回一个匹配项。但是,它也可以返回匹配列表。那么没有匹配项就是空列表(它也是“ falsey”;这是我仅使用None来查看是否得到任何东西的情况之一)。

因此,当在异常和if x之间选择以指示失败时,必须确定None是否为预期的非失败值,然后查看调用该函数的代码的期望。如果“正常”的期望是将返回一个有效值,并且无论是否返回一个有效值,调用者仅偶尔能够正常工作,那么您应该使用异常来指示失败。如果没有有效值是很常见的,那么调用者将期望同时处理这两种可能性,那么您可以使用None

Python pytz时区函数返回的时区为9分钟 - python

由于某些原因,我无法从以下代码中找出原因:>>> from pytz import timezone >>> timezone('America/Chicago') 我得到:<DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD…

Python Pandas导出数据 - python

我正在使用python pandas处理一些数据。我已使用以下代码将数据导出到excel文件。writer = pd.ExcelWriter('Data.xlsx'); wrong_data.to_excel(writer,"Names which are wrong", index = False); writer.…

Python GPU资源利用 - python

我有一个Python脚本在某些深度学习模型上运行推理。有什么办法可以找出GPU资源的利用率水平?例如,使用着色器,float16乘法器等。我似乎在网上找不到太多有关这些GPU资源的文档。谢谢! 参考方案 您可以尝试在像Renderdoc这样的GPU分析器中运行pyxthon应用程序。它将分析您的跑步情况。您将能够获得有关已使用资源,已用缓冲区,不同渲染状态上…

我如何使用linux中的find命令知道python模块的位置 - python

                                                                                                                    我如何使用linux中的find命令知道python模块的位置我对python和linux很陌生。而且不知道如何找到特定的模块或…

在Mac上的终端中停止python - python

在Mac上的终端中使用python,键入ctrl-z 将停止python,但不退出它,给出如下输出:>>> [34]+ Stopped python 如您所见,我已经停止了34个python调用。虽然我可以用>>> exit() 退出python,问题是:是否有一个快捷键可以真正在终端中退出(而不只是停止)python?而…