【问题标题】:Is it a good practice to use a one time loop to simulate goto in python?在 python 中使用一次性循环模拟 goto 是一种好习惯吗?
【发布时间】:2018-04-20 00:46:50
【问题描述】:

goto 通常被认为是邪恶的,不鼓励使用。但有时goto 会提供更清晰、更易读的代码组织,例如: 我想做一些一步一步的计算,每一步的结果决定是否需要以下步骤,如果需要,走哪个分支。逻辑本身有点复杂,所以有几个嵌套的 if 语句。假设 goto 在 python 中可用,实现此目的的一种巧妙方法是:

do_something 
if ...:
    goto zero
do_something
if case 1:
    do_something
    if ...:
        goto zero
    do_something
elif case 2:
    do_something
    if ...:
        goto zero
    do_something
....
result = compute_result(....)
goto next

zero:
result = 0

next:
do_something

没有goto 的帮助,可以通过引入布尔变量来存储标志并添加额外的if 测试来打开或关闭代码来获得相同的行为。但是这种方式使控制流的可读性大大降低。一种解决方法是滥用一次性for 循环来模拟上述代码的goto 版本,如下所示:

zero = True
for _ in range(1):
    do_something 
    if ...:
        break
    do_something
    if case 1:
        do_something
        if ...:
            break
        do_something
    elif case 2:
        do_something
        if ...:
            break
        do_something
    ....
    zero = False

if zero:
    result = 0
else
    result = compute_result(....)

do_something

我的问题是,这是编写更具可读性的代码的最佳方法吗?

【问题讨论】:

  • if case 1: 无论如何都是无效的语法...
  • @Julien 所以...。这是伪代码。
  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 On topichow to ask 在这里申请。 StackOverflow 不是设计、编码、研究或教程服务。我认为,一旦您完成了 Python 教程,您将学习到正确的控制结构,这样 这些大纲对您来说都不“好”。
  • 嗯,只有我明白他在问什么吗?!

标签: python loops goto


【解决方案1】:

尽早中断计算的一种简单方法是使用异常:

class ExitCalculation(Exception): pass

try:
    do_something
    if time_to_goto_zero:
        raise ExitCalculation()
    do_something
    if ...:
        do_something
        if time_to_go_to_zero:
            raise ExitCalculation()
    result = compute_result()
except ExitCalculation:
    result = 0

do next thing

【讨论】:

    【解决方案2】:

    异常提供了相同类型的结构化跳转,没有重复执行的暗示:

    class Foo(Exception):
        pass
    
    try:
        do_something
        if ...:
            raise Foo
        do_something
        if case_1:
            do_something
            if ...:
                raise Foo
            do_something
        elif case_2:
            do_something
            if ...:
                raise Foo
            do_something
    except Foo:
        result = 0
    else:
        result = compute_result(...)
    

    您使用哪些异常是您的“goto”为何会破坏常规控制流的问题。

    【讨论】:

    • 我知道异常做同样的事情,但是使用异常来做控制流被认为是一种不好的做法吗? softwareengineering.stackexchange.com/questions/189222/…
    • 我想说这取决于使用异常是否提供比重度嵌套的if 语句更具可读性的代码。
    • 异常处理流控制的一种形式;您只是不想在有更清晰替代方案的地方使用它。 Python 本身使用两种异常类型(StopIterationSystemExit)进行流控制。
    • 我有点同意你的看法。你认为 for-break 和 try-raise-except 哪个更好?我认为它们具有可比性,与 goto 版本相比,它们都有些丑。
    • 好吧,我发布了一个基于异常的答案,而不是简单地在评论中同意你的 for-break 提议,所以...... :)
    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    • 2021-07-15
    相关资源
    最近更新 更多