当前位置:  开发笔记 > 编程语言 > 正文

在python中使用try vs if

如何解决《在python中使用tryvsif》经验,为你挑选了3个好方法。

在测试变量有值时,是否有理由决定使用哪一个try或哪些if结构?

例如,有一个函数返回列表或不返回值.我想在处理之前检查结果.以下哪一项更可取,为什么?

result = function();
if (result):
    for r in result:
        #process items

要么

result = function();
try:
    for r in result:
        #process items
except TypeError:
    pass;

相关讨论:

检查Python中的成员是否存在



1> Tim Pietzcke..:

你经常听到Python鼓励EAFP风格("比平等更容易要求宽恕")而不是LBYL风格("先看看你跳跃").对我来说,这是效率和可读性的问题.

在您的示例中(假设不是返回列表或空字符串,函数返回列表或者None),如果您希望99%的时间result实际上包含可迭代的内容,我会使用该try/except方法.如果异常真的很特殊,它会更快.如果resultNone的时间超过50%,则使用if的可能会更好.

通过一些测量来支持这一点:

>>> import timeit
>>> timeit.timeit(setup="a=1;b=1", stmt="a/b") # no error checking
0.06379691968322732
>>> timeit.timeit(setup="a=1;b=1", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.0829463709378615
>>> timeit.timeit(setup="a=1;b=0", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.5070195056614466
>>> timeit.timeit(setup="a=1;b=1", stmt="if b!=0:\n a/b")
0.11940114974277094
>>> timeit.timeit(setup="a=1;b=0", stmt="if b!=0:\n a/b")
0.051202772912802175

因此,虽然if声明总是花费你,但设置try/except块几乎是免费的.但Exception实际发生时,成本要高得多.

道德:

完全可以(和"pythonic")try/except用于流量控制,

但是,当Exceptions实际上是例外时,它最有意义.

从Python文档:

EAFP

比许可更容易请求宽恕.这种常见的Python编码风格假设存在有效的键或属性,并且如果假设被证明是错误则捕获异常.这种干净,快速的风格的特点是存在许多 tryexcept陈述.该技术与 许多其他语言(如C)共有的LBYL风格形成对比.


....这是为什么很难为Python做一个真正的优化JIT的原因之一.正如最近的测试版LuaJIT 2所证明的那样,动态语言可能真的非常快; 但它在很大程度上取决于最初的语言设计和它鼓励的风格.(在相关的说明中,语言设计就是为什么即使是最好的JavaScirpt JIT也无法与LuaJIT 1相比,更不用说2)
我知道这是一个陈旧的答案:使用带有timeit的`1/1`这样的语句不是一个很好的选择,因为它们会被优化掉(参见`dis.dis('1/1')`并注意到没有分裂发生).

2> Brandon..:

您的函数不应返回混合类型(即列表或空字符串).它应该返回一个值列表或只返回一个空列表.然后你不需要测试任何东西,即你的代码崩溃到:

for r in function():
    # process items


这引出了一个问题:包装器应该使用if还是尝试处理不可迭代的情况?
在这一点上我完全同意你的意见; 但是,功能不是我的,我只是使用它.
@artdanil:所以你可以将那个函数包装成你编写的函数,就像Brandon Corfman所想的那样.

3> tzot..:

如果我提供的代码乍一看并不明显,您必须在代码示例后阅读说明,请忽略我的解决方案.

我可以假设"没有返回值"表示返回值是None吗?如果是,或者如果"无值"是布尔方式的假,则可以执行以下操作,因为您的代码基本上将"无值"视为"不迭代":

for r in function() or ():
    # process items

如果function()返回的内容不是True,则迭代空元组,即不运行任何迭代.这基本上是LBYL.

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有