python变量等于none-在python中,如何测试变量是否为none、true或false

我有一个函数可以返回以下三项之一:

成功(True)

故障(False)

读取/分析流时出错(None)

我的问题是,如果我不想对True或False进行测试,我该如何查看结果。以下是我目前的做法:

1

2

3

4

5

6

7result = simulate(open("myfile"))

if result == None:

print"error parsing stream"

elif result == True: # shouldn"t do this

print"result pass"

else:

print"result fail"

它真的像删除== True部分一样简单,还是应该添加一个tri-bool数据类型。我不希望simulate函数抛出异常,因为我只希望外部程序处理一个错误,那就是记录并继续。

你问错了问题;你应该请求帮助定义你的结果…您认为"失败"和"错误分析流"有什么区别,它们是什么意思,后果是什么,调用方在每种情况下可能希望采取什么行动(通过、失败、分析错误)?

我在模拟一个电力系统,如果人们失去房子的电力,那就是一个故障。如果我不能读取模拟文件,那么这是一个完全不同的错误。

不清楚(可能是因为这不是一个好主意)为什么你要避免使用一个异常来表示一个异常情况。有什么东西让你相信例外是"重的"、慢的,还是这种情况有其他问题?保罗的答案显示了我们应该如何使用Python。

在simulate函数内,我捕获所有异常;我不希望模拟器内发生的任何事情停止程序的其余部分运行(并处理下一个元素)。但答案让我改变了主意。

例外是件好事。它们是您如何执行诸如验证输入、调试、修复设计、警告用户其问题受到限制等操作的。

问题是我要让这个程序在晚上运行。我不希望它在出错时停止,只要记录下来继续。然后在早上我可以修复错误并重新运行那些错误。

@詹姆斯·布鲁克斯:对。这就是Try/Except处理的全部内容。如果你的simulate有它能捕捉并重试的东西,那就好了。但如果"失败",则不应返回None。它应该只对调用它的脚本引发一个异常。不管怎样,simulate都可以完成。返回None并不如引发一个适当的异常——或者允许异常通过simulate传播到调用脚本中进行处理那样有用。

我懂了。如果simulate是一个外部库,那么我希望它抛出一个异常。它正好更合身。在我的例子中,调用代码可以执行所有操作,记录并继续执行。(根据保罗·麦奎尔的回答)

@詹姆斯,除了一个笼统的except:声明也是一个非常坏的主意。除其他问题外,它将捕获异常类层次结构中不是StandardError的后代的异常,而您几乎不想这样做。

@彼得,为什么是个坏主意?如果有什么导致内部模拟器抛出,那么我想将其记录为一个错误。我真的不希望我的程序停止处理,仅仅是因为它模拟的某件事抛出了一个我没想到的错误。在这种情况下我该怎么办?

@詹姆斯,用except Exception:代替。这捕获了所有"真正的"错误,以及Warning和StopIteration。它允许KeyboardInterrupt和SystemExit通过。如果你真的想抓住这些,最好是使用另一个外部的尝试/例外或者其他清晰地记录你意图的结构,因为这些不是"错误"。(但我确实说过"几乎从来没有"……也许在你的情况下,你真的想抓住一切,甚至阻止ctrl-c或sys.exit()退出,等等。)

谢谢你的澄清。我认为你是对的,我不应该抓住KeyboardInterrupt(或者其他人),但我不想冒险不抓住其他东西(也许那些不能从例外中正确继承的东西)。基本上我意识到这很糟糕,无论如何我都会这么做。

否决了请更正标题以反映基本问题和接受的答案。

1

2

3

4

5

6if result is None:

print"error parsing stream"

elif result:

print"result pass"

else:

print"result fail"

保持简单和明确。当然,你可以预先定义一本字典。

1

2messages = {None: "error", True: "pass", False: "fail"}

print messages[result]

如果计划修改simulate函数以包含更多返回代码,那么维护此代码可能会有点问题。

simulate还可能引发解析错误的异常,在这种情况下,您要么在这里捕获它,要么让它向上传播一个级别,如果else语句,打印位将减少到一行。

后者是对真假的一种明确的检验,不是吗?

当然,但是知道这些只是可能的返回值,我认为这不是问题。

而且似乎也快了一点

a="foo"如果a:print"its true"a实际上不是真的,它只是不是空的。

别害怕例外!让您的程序只需登录并继续,就可以轻松做到:

1

2

3

4

5

6

7

8

9

10

11try:

result = simulate(open("myfile"))

except SimulationException as sim_exc:

print"error parsing stream", sim_exc

else:

if result:

print"result pass"

else:

print"result fail"

# execution continues from here, regardless of exception or not

现在,您可以从Simulate方法得到更丰富的通知,了解到底出了什么问题,以防您发现错误/无错误信息不够丰富。

同意。比上面明显更流行的解决方案(闻起来太像C代码)要多得多。

@布兰登不同意。这段代码比上面的解决方案(或下面的改进版本)更长,更糟糕,更不可读:更多缩进,更多不同的语句-猜猜为什么后者更流行,正如您所说…;-)如果这会导致更尴尬的代码,为什么要尝试成为"Python"?

现在打印跟踪而不是"错误分析流",你得到了我的投票。

好吧,不管怎样,你得到了我的选票,但我的意思是打印一些类似于traceback.format_exc()的东西。看看这个答案。

打印一个回溯并不总是可行的,尤其是当这是一个将输出传输给最终用户的区域时。当然,记录跟踪,但对用户来说,它们是不受欢迎的gobbledygook——它们需要一条摘要错误消息,最好提供关于它们可以如何修复错误的建议(如果有的话)。

许多人都会来到这个页面,寻找标题问题的答案。对我们大多数人来说,"不要害怕例外!"与我们的处境无关。我们只需要测试真假。虽然您建议的备选方案对某些情况是有效的,但我认为最好在问题被问到时也包括一个答案。

从不,从不,从不说

1if something == True:

从未。这太疯狂了,因为您要重复冗余地为if语句指定为冗余条件规则的内容。

更糟的是,永远,永远,永远,永远不要说

1if something == False:

你有not。请随意使用。

最后,执行a == None是无效的。做a is None。None是一个特殊的单例对象,只能有一个。检查一下你是否有那个物体。

我知道这是一个坏主意,这就是为什么我发布了这个问题,从表面上看,它更多的是一种代码味道,而不是我想的。谢谢你的信息

与True的平等性测试并不是多余的(尽管我同意这是不明智的)。它可以调用__eq__或其他特殊的方法,这实际上可以做任何事情。

@斯科特·格里菲斯:很好。这真是一个非常可怕的场景。如果事实上是这样的话,这个程序违反了我们的基本期望,在某种程度上,它需要简单地从零开始删除和重写,而不需要这种黑色魔法。

"从不,从不,从不"…?有些情况下,虽然if something == True产生的结果与if something不同,例如,对于非布尔something。2==True产生假,而2的计算结果为真;None==False是假,但not None是真的!

-1由于@rolf bartstra所说的是真的,所以这个答案误导了我们,完全不正确。虽然在这种情况下,您所说的可以应用。

有时有很好的理由来测试某物是True、False还是None,例如,从数据库打印值,其中NULL分别表示"未知状态"和"真/假"表示"是/否"。

- 1。由于something的任何非零或非空或非零长度值返回bool(something)上的True。在这种情况下,如果您只想检查something的值是否为True,即bool。那你就得在我看来做一件事。

关于@rolfbartstra的评论:实际上,我认为这是不使用== True的一个很好的理由。如果有可能something不是布尔值,那么我们在那里实际测试什么?在python 2中,甚至不能保证1将等于True(见此处)。所以我觉得S.Lott的建议绝对明智。

我想强调的是,即使在某些情况下,由于要确保expr是True而不是仅仅与0或None不同,所以is也会因为同样的原因而优先于==。lott提到避免== None的原因。

它确实稍微更有效率,而且,蛋糕上的樱桃色,更具人类可读性。

输入:

1

2

3

4

5

6

7

8from time import time

t0 = time()

print ( ( 1 == 1 ) == True )

t1 = time()

print ( ( 1 == 1 ) is True )

t2 = time()

print "{:e}s

{:e}s".format( t1-t0, t2-t1)

输出:

1

2

3

4True

True

1.201630e-04s

8.797646e-05s

你不能只运行一次基准测试就说其中一个比另一个更有效(即使可能如此)。运行多次(10000)以查看它的平均行为。

我认为对你的情况来说,提出例外是个更好的主意。另一种方法是返回元组的模拟方法。第一项是状态,第二项是结果:

1

2

3

4

5result = simulate(open("myfile"))

if not result[0]:

print"error parsing stream"

else:

ret= result[1]

返回tuple通常与解包tuple一起使用;)

但是,您的代码没有多大意义,如果返回False,它将打印"error parsing stream"。

Simulate方法应返回(false,"anything at all")或(true,ret),其中ret为false或true。

好吧,你在定义输出值以适应你的逻辑,没有解释就不清楚了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值