Python 中“try”语句的可选“else”子句的预期用途是什么?

2024-12-30 08:42:00
admin
原创
101
摘要:问题描述:else该语句的可选子句的预期用途是什么try?解决方案 1:else如果执行超出了底部,则执行块中的语句try- 如果没有异常。老实说,我从未发现过这种需要。但是,处理异常指出:使用 else 子句比在 try 子句中添加额外的代码更好,因为它可以避免意外捕获未由 try ... except 语...

问题描述:

else该语句的可选子句的预期用途是什么try


解决方案 1:

else如果执行超出了底部,则执行块中的语句try- 如果没有异常。老实说,我从未发现过这种需要。

但是,处理异常指出:

使用 else 子句比在 try 子句中添加额外的代码更好,因为它可以避免意外捕获未由 try ... except 语句保护的代码引发的异常。

因此,如果您有一个方法,例如,可以抛出一个IOError,并且您想要捕获它引发的异常,但是如果第一个操作成功,您还想做其他事情,并且您不想从该操作中捕获 IOError,您可以编写如下代码:

try:
    operation_that_can_throw_ioerror()
except IOError:
    handle_the_exception_somehow()
else:
    # we don't want to catch the IOError if it's raised
    another_operation_that_can_throw_ioerror()
finally:
    something_we_always_need_to_do()

如果您只是将其放在another_operation_that_can_throw_ioerror()之后operation_that_can_throw_ioerrorexcept将会捕获第二个调用的错误。如果您将其放在整个try块之后,它将始终运行,直到 之后才会运行finallyelse让您确保

  1. 第二个操作只有在没有异常的情况下才会运行,

  2. 它在finally块之前运行,并且

  3. 它引发的任何IOError问题都不会在这里得到解决

解决方案 2:

使用它的一个重要原因是else风格和可读性。通常,将可能导致异常的代码放在处理异常的代码附近是一个好主意。例如,比较这些:

try:
    from EasyDialogs import AskPassword
    # 20 other lines
    getpass = AskPassword
except ImportError:
    getpass = default_getpass

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
else:
    # 20 other lines
    getpass = AskPassword

except当无法提前返回或重新抛出异常时,第二种方法很好。如果可能的话,我会这样写:

try:
    from EasyDialogs import AskPassword
except ImportError:
    getpass = default_getpass
    return False  # or throw Exception('something more descriptive')

# 20 other lines
getpass = AskPassword

注意:答案是从这里最近发布的重复内容中复制而来的,因此都是“AskPassword”的内容。

解决方案 3:

Python try-else

elsetry 语句的可选子句的预期用途是什么?

预期用途是,如果没有预期处理的异常,则拥有一个可以运行更多代码的上下文。

这种上下文可以避免意外处理您未预料到的错误。

但了解导致 else 子句运行的确切条件非常重要,因为returncontinuebreak可能会中断到 的控制流else

总之

如果没有异常并且没有被、或语句打断,该else语句就会运行。return`continue`break

其他答案忽略了最后一部分。

来自文档:

else当控制流出子句的末尾时,将执行可选子句try。*

(粗体添加。)脚注如下:

*目前,除了出现异常或执行returncontinuebreak语句的情况外,控制“会从末尾流出”。

它确实需要至少一个前置 except 子句(参见语法)。因此,它实际上不是“try-else”,而是“try-except-else(-finally)”,其中else(and finally) 是可选的。

Python 教程详细阐述了其预期用途:

try ... except 语句有一个可选的 else 子句,如果存在,则必须跟在所有 except 子句之后。它对于在 try 子句未引发异常时必须执行的代码很有用。例如:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

使用 else 子句比在 try 子句中添加额外的代码更好,因为它可以避免意外捕获未由 try ... except 语句保护的代码引发的异常。

区分块else后面的代码的示例try

如果您处理错误,该else块将不会运行。例如:

def handle_error():
    try:
        raise RuntimeError('oops!')
    except RuntimeError as error:
        print('handled a RuntimeError, no big deal.')
    else:
        print('if this prints, we had no error!') # won't print!
    print('And now we have left the try block!')  # will print!

现在,

>>> handle_error()
handled a RuntimeError, no big deal.
And now we have left the try block!

解决方案 4:

一种用途:测试一些应该引发异常的代码。

try:
    this_should_raise_TypeError()
except TypeError:
    pass
except:
    assert False, "Raised the wrong exception type"
else:
    assert False, "Didn't raise any exception"

(在实践中,应该将此代码抽象为更通用的测试。)

解决方案 5:

Try-except-else 非常适合将EAFP 模式与duck-typing结合起来:

try:
  cs = x.cleanupSet
except AttributeError:
  pass
else:
  for v in cs:
    v.cleanup()

你可能会认为这个简单的代码还不错:

try:
  for v in x.cleanupSet:
    v.clenaup()         # <-- deliberate typo
except AttributeError:
  pass

这是意外隐藏代码中严重错误的好方法。我在那里打错了cleanup,但那个AttributeError会让我明白的被吞掉了。更糟糕的是,如果我写得正确,但清理方法偶尔会传递一个具有错误命名属性的用户类型,导致它在中途默默失败并留下一个未关闭的文件,那该怎么办?祝你好运调试那个。

解决方案 6:

我发现当你需要进行清理工作时它非常有用,即使出现异常也必须完成:

try:
    data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
    handle_exception(e)
else:
    do_stuff(data)
finally:
    clean_up()

解决方案 7:

即使你现在想不出它的用途,但你可以肯定它一定有用。这是一个缺乏想象力的示例:

else

a = [1,2,3]
try:
    something = a[2]
except IndexError:
    print("out of bounds")
else:
    print(something)

没有else

try:
    something = a[2]
except IndexError:
    print("out of bounds")

if "something" in locals():
    print(something)

这里something定义了一个变量,如果没有抛出错误的话。你可以从try块外移除它,但如果定义了一个变量,那么就需要进行一些混乱的检测。

解决方案 8:

PEP 380try-else中有一个很好的例子。基本上,它归结为在算法的不同部分进行不同的异常处理。

它是这样的:

try:
    do_init_stuff()
except:
    handle_init_suff_execption()
else:
    try:
        do_middle_stuff()
    except:
        handle_middle_stuff_exception()

这使得你可以在更接近异常发生的位置编写异常处理代码。

解决方案 9:

来自错误和异常 # 处理异常 - docs.python.org

try ... except语句有一个可选else子句,如果存在,则必须跟在所有 except 子句之后。它对于在 try 子句未引发异常时必须执行的代码很有用。例如:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'cannot open', arg
    else:
        print arg, 'has', len(f.readlines()), 'lines'
        f.close()

使用 else 子句比在 try 子句中添加额外的代码更好,因为它可以避免意外捕获未由 try ... except 语句保护的代码引发的异常。

解决方案 10:

try:
    statements # statements that can raise exceptions
except:
    statements # statements that will be executed to handle exceptions
else:
    statements # statements that will be executed if there is no exception

例子 :

try:
    age=int(input('Enter your age: '))
except:
    print ('You have entered an invalid value.')
else:
    if age <= 21:
        print('You are not allowed to enter, you are too young.')
    else:
        print('Welcome, you are old enough.')

输出:

>>> 
Enter your age: a
You have entered an invalid value.
>>> RESTART
>>> 
Enter your age: 25
Welcome, you are old enough.
>>> RESTART
>>> 
Enter your age: 13
You are not allowed to enter, you are too young.
>>> 

复制自:https: //geek-university.com/python/the-try-except-else-statements/

解决方案 11:

查看Python 参考资料,似乎else在没有异常时执行try。当控制流出 try 子句的末尾时,将执行可选的 else 子句。2 else子句中的异常不由前面的 except 子句处理。

深入研究 python有一个例子,如果我理解正确的话,在try块中他们尝试导入一个模块,当失败时你会得到异常并绑定默认值,但是当它工作时你可以选择进入else块并绑定所需的内容(请参阅链接以获取示例和解释)。

如果您尝试在catch块中执行工作,它可能会引发另一个异常 - 我猜这就是else块派上用场的地方。

解决方案 12:

就是这样。try-except 子句的“else”块用于当(且仅当)尝试的操作成功时运行的代码。它既可以被使用,也可以被滥用。

try:
    fp= open("configuration_file", "rb")
except EnvironmentError:
    confdata= '' # it's ok if the file can't be opened
else:
    confdata= fp.read()
    fp.close()

# your code continues here
# working with (possibly empty) confdata

我个人很喜欢它,并在适当的时候使用它。它对语句进行语义分组。

解决方案 13:

我将添加另一个在处理数据库会话时看起来很简单的用例:

    # getting a DB connection 
    conn = db.engine.connect()

    # and binding to a DB session
    session = db.get_session(bind=conn)

    try:
        # we build the query to DB
        q = session.query(MyTable).filter(MyTable.col1 == 'query_val')

        # i.e retrieve one row
        data_set = q.one_or_none()

        # return results
        return [{'col1': data_set.col1, 'col2': data_set.col2, ...}]

    except:
        # here we make sure to rollback the transaction, 
        # handy when we update stuff into DB
        session.rollback()
        raise

    else:
        # when no errors then we can commit DB changes
        session.commit()

    finally:
        # and finally we can close the session
        session.close()

解决方案 14:

我发现这种try: ... else:结构在你运行数据库查询并将这些查询的结果记录到相同类型/类型的单独数据库中时非常有用。假设我有很多工作线程,它们都在处理提交到队列的数据库查询

#in a long running loop
try:
    query = queue.get()
    conn = connect_to_db(<main db>)
    curs = conn.cursor()
    try:
        curs.execute("<some query on user input that may fail even if sanitized">)
    except DBError:
        logconn = connect_to_db(<logging db>)
        logcurs = logconn.cursor()
        logcurs.execute("<update in DB log with record of failed query")
        logcurs.close()
        logconn.close()
    else:

        #we can't put this in main try block because an error connecting
        #to the logging DB would be indistinguishable from an error in 
        #the mainquery 

        #We can't put this after the whole try: except: finally: block
        #because then we don't know if the query was successful or not

        logconn = connect_to_db(<logging db>)
        logcurs = logconn.cursor()
        logcurs.execute("<update in DB log with record of successful query")
        logcurs.close()
        logconn.close()
        #do something in response to successful query
except DBError:
    #This DBError is because of a problem with the logging database, but 
    #we can't let that crash the whole thread over what might be a
    #temporary network glitch
finally:
    curs.close()
    conn.close()
    #other cleanup if necessary like telling the queue the task is finished

当然,如果您可以区分可能引发的异常,则不必使用它,但如果对成功的代码做出反应的代码可能会引发与成功代码相同的异常,并且您不能只放过第二个可能的异常,或者在成功时立即返回(在我的情况下这会杀死线程),那么这确实很方便。

解决方案 15:

也许用途如下:

#debug = []

def debuglog(text, obj=None):
    " Simple little logger. "
    try:
        debug   # does global exist?
    except NameError:
        pass    # if not, don't even bother displaying
    except:
        print('Unknown cause. Debug debuglog().')
    else:
        # debug does exist.
        # Now test if you want to log this debug message
        # from caller "obj"
        try:
            if obj in debug:
                print(text)     # stdout
        except TypeError:
            print('The global "debug" flag should be an iterable.')
        except:
            print('Unknown cause. Debug debuglog().')

def myfunc():
    debuglog('Made it to myfunc()', myfunc)

debug = [myfunc,]
myfunc()

也许这也会给你带来用处。

解决方案 16:

这是我喜欢使用此模式的另一个地方:

 while data in items:
     try
        data = json.loads(data)
     except ValueError as e:
        log error
     else:
        # work on the `data`

解决方案 17:

一个else块通常可以存在来补充每个块中出现的功能except

try:
    test_consistency(valuable_data)
except Except1:
    inconsistency_type = 1
except Except2:
    inconsistency_type = 2
except:
    # Something else is wrong
    raise
else:
    inconsistency_type = 0

"""
Process each individual inconsistency down here instead of
inside the except blocks. Use 0 to mean no inconsistency.
"""

在这种情况下,inconsistency_type在每个 except 块中设置,以便在无错误情况下补充行为else

当然,我将其描述为将来可能出现在您自己的代码中的一种模式。在这个特定情况下,您无论如何都要在块inconsistency_type之前将其设置为 0 try

解决方案 18:

我能想到的一个使用场景是不可预知的异常,通过重试可以规避这些异常。例如,当 try 块中的操作涉及随机数时:

while True:
    try:
        r = random.random()
        some_operation_that_fails_for_specific_r(r)
    except Exception:
        continue
    else:
        break

但是如果可以预测异常,您应该始终选择事先进行验证而不是异常。然而,并非所有事情都可以预测,因此此代码模式有其适用之处。

解决方案 19:

我发现else处理可能不正确的配置文件很有用:

try:
    value, unit = cfg['lock'].split()
except ValueError:
    msg = 'lock monitoring config must consist of two words separated by white space'
    self.log('warn', msg)
else:
     # get on with lock monitoring if config is ok

读取配置的异常lock会禁用锁监控,并且 ValueErrors 会记录一条有用的警告消息。

解决方案 20:

dict.get(key)假设你的编程逻辑取决于字典中是否有给定键的条目。你可以使用构造来测试结果if... else...,也可以执行以下操作:

try:
    val = dic[key]
except KeyError:
    do_some_stuff()
else:
    do_some_stuff_with_val(val)

解决方案 21:

可以使用此构造在finally子句中以常见的方式处理异常,而当没有异常时执行其他操作:

class TooManyRetries(RuntimeError):
    pass


n_tries = 0
max_retries = 2
while True:
    try:
        n_tries += 1
        if n_tries >= max_retries:
            raise TooManyRetries
        fail_prone_operation()
    except Exception1 as ex:
        # handle1
    except Exception2 as ex:
        # handle2
    except Exception3 as ex:
        # handle3
    except TooManyRetries as ex:
        raise
    else: # No exception
        n_tries = 0
    finally:
        common_restore_state()
        continue

    

解决方案 22:

else:块令人困惑且(几乎)无用。它也是forandwhile语句的一部分。

实际上,即使在if-statement 上,也else:可能以真正可怕的方式被滥用,从而产生很难发现的错误。

考虑一下。

   if a < 10:
       # condition stated explicitly
   elif a > 10 and b < 10:
       # condition confusing but at least explicit
   else:
       # Exactly what is true here?
       # Can be hard to reason out what condition is true

三思而后行else:。这通常是一个问题。除了在if- 语句中,请避免使用它,即使这样,也要考虑记录else- 条件以使其明确。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用