python块中的冒号在技术上是必要的吗?


19

这实际上只是想要了解更多信息的python新手的理论问题。

在python中的块初始语句之后,我一直忘了冒号。这些就是我的意思:

  • for <variable> in <sequence>:
  • if <blah blah>:

我的想法是,我一直忘记的一个原因是它们实际上是隐式的:不管是否冒号,该语句都以该行结尾。

我的问题-为了学习python语法如何工作而问-是冒号是否真的不必要?我是否要更改python语法,以便不再需要冒号,是否会中断?这会使某些陈述模棱两可或不可能吗?


4
我认为您不明白这个问题,即语法是否必须使用冒号。另外,无论您的答案是什么,它都应包含一个解释。
托马什Zato -恢复莫妮卡

可能,您能否改写问题的一部分,以便您从这个问题的见解中受益,也许是一个例子?你将是最好的法官,我想我对你问的意图一无所知。您是在解释器/编译器的分析器级别上指的吗?谢谢你
bhan sur

我不知道该怎么说。我的问题主要是,如果你可以改变所有Python语法,使其后不再需要结肠ifelsewhile等等。如果这样做的话,python仍然是可以毫无歧义地使用的语言吗?
托马什Zato -恢复莫妮卡

得到它了!这是有关python语法设计决策的问题。对不起,误会了。感谢您的解释。
bhan sur

推测。好像换行符在实践中很难由口译员/解析器检测到,或者在那里易于阅读。在LUA中,您可以if .. then .. end单行编写。所以在python中,这里用thena :和必需的换行符代替了两件事。其中之一似乎是多余的。
bhan sur

Answers:


9

是的,要求结肠消除某些结构的歧义。例如,考虑if x - y < z: pass。没有冒号,我们将无法在不知道x,y和z是什么上下文的情况下决定如何解析它。if x: -y < z...如果x为布尔值if x - y < z:则有效,否则为有效。

对于编程语言来说,不要求您执行要编译的应用程序才能解析该应用程序是一个很好的主意,因此非常需要冒号。您可以删除它,但是您需要其他方法来消除歧义。


1
等一下,您可以在冒号后的同一行上声明吗?我很确定这是不允许的。
托马什Zato -恢复莫妮卡

1
它是允许的,但之后只能换行。
Phoshi

还是有些困惑。是否允许:if condition: print("Condition passed")\n允许?该\n符号表示print语句后的新行。
托马什Zato -恢复莫妮卡

当然,请尝试一下。
RemcoGerlich

1
@TomasZato:是的,您可以在冒号后面有任何语句。它会立即终止该块,因此,当该块是一个小的衬板时,它主要有用。
Lie Ryan

14

如果不是在另一个世界中设计Python,那么在语法上实际上并不需要冒号,这很可能是语言设计人员可能不会决定要求冒号的原因。确实,像眼镜蛇这样的语言可以做到这一点。

python中需要冒号的主要原因是人类可读性。引用Python常见问题解答

为什么if / while / def / class语句需要冒号?

冒号主要是为了增强可读性(实验性ABC语言的结果之一)。考虑一下:

if a == b
    print(a)

if a == b:
    print(a)

请注意,第二个稍微更易于阅读。请进一步注意冒号如何引起此FAQ回答中的示例;这是英语的标准用法。

另一个次要原因是冒号使使用语法突出显示的编辑器更容易。他们可以寻找冒号来决定何时需要增加缩进量,而不必对程序文本进行更复杂的解析。

正如常见问题解答中提到的那样,冒号还使在不完全解析语言的情况下更轻松地处理python代码。任何具有完整解析器的文本处理器,包括python编译器,都可以在不需要冒号或明确时将其设为可选的情况下不使用冒号。


3
“请注意,第二个稍微容易阅读。”我发现第一个更容易阅读。噪音小。
user76284

10

对于计算机,这不是必需的,但对于人类来说则是必需的。

Guido van Rossum(Python的创建者)有一阵子的Python历史博客。冒号是在ABC中引入的,ABC是Python许多功能的来源。

对“卡琳·杜瓦,压痕和科隆”这个博客帖子,圭多写道:

在这里,我应兰伯特的要求解释。

1978年,在位于波兰Jabłonna的一栋豪宅的设计会议中,Robert Dewar,Peter King,Jack Schwartz和Lambert通过比较每个替代方案中记录的(气泡)气泡排序实现,比较了B的各种替代提议语法。由于他们不同意,罗伯特·杜瓦(Robert Dewar)的妻子从房间里被叫来征求她的意见,就像现代巴黎要求比较赫拉(Hera),雅典娜(Athena)和阿芙罗狄蒂(Aphrodite)的美丽一样。但是在向她解释了第一个版本之后,她说:“您的意思是,在上面写着:'FOR i ...'的那一行中,必须在后面的行中这样做;而不仅仅是那行? !!” 在这里,科学家们意识到,如果在该行的末尾出现一个冒号,就可以避免误解。

(这里的B是导致ABC的一系列原型语言B0,B1,...。不是C的前身是B语言)。

我还记得Guido在90年代指出这是为了编辑的利益,它可以在以冒号结尾的行之后自动插入缩进。但是我还没有找到这个来源。


4

眼镜蛇编程语言的语法在很大程度上受到Python的启发,它摒弃了结肠,如此看来,这不是绝对必要的。但是,删除冒号是不够的,还需要对语法进行其他更改。例如,请参阅我的一个玩具项目中的这段代码

kons  = lambda hd, tl: lambda x: hd if x else tl
virst = lambda l: l(True )
rrest = lambda l: l(False)

如果没有冒号将主体与参数列表分开,我将不得不使用缩进:

kons  = lambda hd, tl
    lambda x
        hd if x else tl

virst = lambda l
    l(True )

rrest = lambda l
    l(False)

我相信眼镜蛇的早期版本使冒号成为可选项,您可以使用缩进或冒号或同时使用两者。与它在Ruby中的工作方式类似,在这里有一些关键字可以分隔控件表达式的不同部分,但是您也可以使用表达式分隔符(分号或换行符):

# idiomatic
while true do puts "I am awesome" end
#          ↑↑

# non-idiomatic, but legal
while true; puts "I am awesome" end
#         ↑

# non-idiomatic, but legal
while true
puts "I am awesome" end

# idiomatic
while true
  puts "I am awesome"
end

在当前版本的Cobra中,可以使用逗号:

if x
    y

可以写成

if x, y

您需要某种方式来分隔控件表达式或定义的不同部分。在Python中,这就是冒号。如果删除冒号,则需要用其他东西代替它,例如,强制缩进。删除冒号将无效。

绝对确定的唯一方法是使用和不使用冒号对语法进行形式化,并证明其无歧义。

但是请注意,Python Zen的格言之一是“显式优于隐式”,因此使用冒号对块进行显式划分似乎符合Python的一般原理。该设计与历史常见问题也提到,这项决定是基于Python的前任,美国广播公司的经验证据。


3
好了,有了上一段中描述的哲学,您可能需要在每一行的末尾加冒号。显式vs隐式只有在显式实际添加信息时才有意义(例如,隐式变体是模棱两可的)。这是我的问题的重点。
托马什Zato -恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.