Python,为什么需要elif关键字?

72

我刚开始学习Python编程,想了解一下elif关键字。

我之前使用过其他编程语言,使用的是else if。有没有人知道Python开发者为什么要添加额外的elif关键字?

为什么不这样:

if a:
    print("a")
else if b:
    print("b")
else:
    print("c")

3
看看 Ruby,它可以做同样的事情。在我看来,这并不值得过多思考。 - Mark Snidovich
2
看看 Perl 中的 elsif - slebetman
3
请查看 bash/sh 中的 elif 部分。将其翻译为“同时也要查看bash / sh中的'elif'部分”。 - slebetman
11
如果你花时间去了解更多编程语言,你会发现这并不奇怪。你现在遇到的只是因为你对编程语言缺乏接触经验所导致的感受。 - slebetman
2
所以,你基本上是在问为什么它被称为“elif”而不是“elseif”或“else if”,对吧?而不是为什么有一个“elif”控制结构? - JAL
显示剩余6条评论
8个回答

122
据我所知,这是为了避免过多缩进。您可以写

if x < 0:
    print 'Negative'
else:
    if x == 0:
        print 'Zero'
    else:
        print 'Positive'
但是。
if x < 0:
    print 'Negative'
elif x == 0:
    print 'Zero'
else:
    print 'Positive'

感谢ign提供的文档参考:

elif关键字是“else if”的缩写,可避免过多缩进,让代码更加简洁易读。


只是更加美好。


56
@Adam:如果elseif在同一行中,那么else if怎么办?我认为这就是原帖的意思。 - Manoj Govindan
18
"else if" 并不总是一个单独的关键字。例如,在 C# 中,它只是一个嵌套的 if,类似于我在第一个示例中编写的方式。只是 C# 不像 Python 那样关心空格,因此可以将 "else if" 写在一行上是有效的。至于为什么叫做 "elif" 而不是 "elseif"、"elsif" 或其他任何名称,我不知道。各种语言都是不同的,仅因为某些语言采用了某种方式,不意味着每个人都必须遵循。:) - Adam Lear
2
只是为了增加一些背景和来源:http://docs.python.org/2/tutorial/controlflow.html - Ignacio
3
从来没想到 C 语言里的 else if 可以简写成 elseif,我一直把它看作是一个关键字,但这种写法更合理。C 是一种没有固定风格的小语言(这就是为什么 Python 需要额外的 elif),使用带有空格的单个关键字会让人感到奇怪。谢谢哈! - Jori
2
在我看来,这个答案值得被采纳。我的直觉是elif被选择是为了保持良好的对齐(else和elif共享相同数量的字符),并将编辑器列宽保持到最小(“else if”关键字占用了比条件更多的空间),但这只是我的猜测。 - rjs
关于不使用'else if',我认为这是编译器的便利之处。这样词法分析器就不需要向前查看,使用传统的词法分析器更容易实现。虽然我认为使用"else if"而不是"elif"不会有理论问题。 - Iman Akbari

83

类C语言语法的编程语言会自带else if而无需额外实现。

原因是该语法中的控制结构只是针对下一条语句进行操作,如果需要,它可以是用括号括起来的复合语句(例如{ x += 1; y += 1 })。

这意味着一旦您已经实现了ifelseelse if就会自然而然地免费获得语言语法上的支持,无需进一步实现。为了理解其中的原因,请看这个例子:

if (condition) {
    if_body();
} else if (another_condition) {
    else_if_body();
} else {
    else_body();
}
这看起来像是一个带有复合语句的ifelse ifelse的结构。但实际上它不是,这实际上是两个单独的if语句,每个都有一个else语句;第二个if语句位于第一个if语句的else体内。 else if { ... } 实际上被解析为应用于下一条语句的else,该语句是一个(应用于复合语句{ else_if_body(); }的)if语句。然后最终的else绑定到紧接着的前一个if语句,即第二个if语句。
以下是相同内容按照解析方式更明确的描述1:
if (condition) {
    if_body();
} else {
    if (another_condition) {
        else_if_body();
    } else {
        else_body();
    }
}

但事实证明,如果语言直接将else if作为if语句的一级选项实现,它将与第二个独立的位于第一个else中的if语句完全相同!所以根本没有必要实现else if;一旦实现了ifelse,语言实现者就可以通过这种语法风格免费获得else if

Python的语法不允许这种免费的操作。

C语言风格的编程人员可以在思考时使用else if,即使该语言只有恰好有零个或一个else,但这仅因为他们可以编写格式化方式与人类读者看起来不同于编译器的第一个示例代码。

另一方面,Python使用缩进来表示块结构,这迫使块结构对于解释器和人类读者来说看起来是相同的2。一旦你用Python语法风格实现了ifelse,程序员仍然可以编写行为与else-if完全相同的代码,方法是在第一个else中放置第二个if语句。但是,这看起来像这样:

if condition:
    if_body()
else:
    if another_condition:
        else_if_body()
    else:
        else_body()

当你有多个else-if时,使用嵌套的if语句会使代码变得复杂难懂,看起来也很丑。因此,值得添加一个明确的语言特性来恢复使用else-if的能力。尽管这技术上使语言更加复杂,但实际上使得基于语言思考更简单了,所以它是好的复杂性。使用手动构建的嵌套if语句和else语句序列时,读者必须手动阅读所有代码,并验证除了最后一条外的每个else都只包含一个if语句而没有其他内容,才能得出结论:整个序列等价于按顺序检查的线性条件链,并在第一个成功的条件检查时执行一些代码。

因此,我们可以看到,具有类C语法的编程语言可以使用else if,因为它们已经拥有了这个特性。这就是它存在的原因。具有类Python语法的编程语言必须显式地做一些事情才能得到可用作else-if的结构。为什么他们选择了elif?这是任意的;您必须向制定决策的人询问。

然而,Python并没有发明elif,它早在Python存在之前就已经存在于其他编程语言中。因此,我猜当他们不得不实现一个明确的else-if结构时,他们只是选择了程序员已经熟悉的一个。


1从技术上讲,这是那些真正重视在控制结构中始终使用大括号的人应该编写的代码。

2您肯定可以构造反例,但这是基于缩进的语法的一般思想。


5
对于您的第一个脚注:所有C语言风格指南都说“控制结构总是使用大括号”,然后有一个v1.1版本,在其中某人潦草地写上了“除了else if”。每个自动格式化或样式检查器都有一个v1.1版本,相对简单的解析树增加了一个丑陋的特殊情况else if。每种“更好的C语言”设计都要求使用大括号,然后添加例外情况,打破其一张明信片大小的语法和简单的解析器。(或者他们只是添加了elif/elsif/elsei关键字。) - abarnert

17

为避免“括号^H^H^H^H^H else if”战争。

在C/C++中,当你使用else if时,可以以许多不同的方式组织你的代码:

if (...) {
    ...
} else if (...) {
    ...
}


if (...) {
    ...
} 
else if (...) {
    ...
}

if (...) {
    ...
} else 
if (...) {
    ...
}

// and so on

如果改用elif,就不会发生这种错误了,因为只有一种方法可以写一个elif。此外,elifelse if更短。


19
最后一个例子看起来很痛苦。哀哉施此于你无辜的眼睛者。 - SingleNegationElimination
20
如果Python中存在else if,我无法理解它会如何导致大括号之争。 - ypercubeᵀᴹ
5
@ypercube:http://answers.google.com/answers/threadview/id/386870.html - Lie Ryan
@LieRyan,你提供的链接完全没有回答ypercube的问题,那是关于^H^H^H^H^H表达式的,与问题毫不相关。 - Roland Pihlakas

9

这就是事实。 Javascript 使用else ifphp 使用elseifperl 使用elsif,C预处理器和python使用elif。它们都没有错,只是选择了略有不同的语法来完成相同的事情。 :D


4
直到看到这个答案,我才意识到C使用else if而C++使用elif,因此在单个文件中通常会混用两者。 - ArtOfWarfare

7

我发现它们很有帮助,可以帮助区分“else-if”和“最后的else”。


-2

elif是一种在其他语言中用作switch替代的功能,但具有更强大的功能。

例如,在C语言中,您可以编写:

switch (number){
 case 1:
   doA()
   break;
 case 2:
   doB()
   break;
 case N:
   doN()
   break;
 default:
   doSomethingElse()
   break;
}

在Python中,您可以编写:

if number == 1: doA()
elif number == 2: doB()
elif number == N: doC()
else: doSomethingElse()

正如您所看到的,elif比switch更强大,因为您可以放置更复杂的语句,并避免嵌套if/else语句。


2
不,elif是C语言中else if的类比,具有完全相同的功能(尽管它是使用不同的解析规则实现的)。即使在C语言中,您也可以使用else if代替case。这当然与为什么Python中使用elif而不是else if无关。 - Ben

-3

很可能这只是语法糖。就像 Visual Basic 中的 Wend 一样。


24
我不确定这实际上如何回答为什么Python实现者选择使用 elif 而不是 else if 的问题。 - Ben
14
elif并不仅仅是else if的简写。实际上,在Python 2和Python 3中,else if是语法错误。请注意,这并非解释。 - JSQuareD
@JSQuareD 这是真的,但就像 elif 被添加为特殊情况一样,同样可以在 else 后面没有冒号的情况下添加 else if - Neme

-8

Python从Perl继承了这一点,在Perl中它被称为elsif

在Python的情况下,将else if作为C语言样式中的两个独立结构将会非常丑陋,因为您必须使用两个缩进级别else: if:

特殊处理这两个关键字是否更好仍有争议(使else if成为单个结构,如not in运算符)。

PL / SQL也有elsif,C预处理器将其拼写为elif


20
“Python继承自Perl” - 什么? - user395760
5
我认为它们都是从之前的语言中得来的 - Python根本不是Perl的后代。 - Mark Snidovich
4
如果用Bash代替Perl的话,将会更好,因为在Bash中是确实有elif这个语法的。我认为Bash是从比Perl更古老的sh继承而来的。 - slebetman
7
"elif" 出现在 Algol 68 中(http://en.wikipedia.org/wiki/ALGOL_68)。 - Andrew Dalke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接