当我运行下面的代码时,这些代码的函数内部有空白行(没有空格),当在解释器模式和python3 split.py
中逐行运行代码时,我的行为与Python 3.6.5不同:>
# File split.py
def find(s, start, predictor):
for i in range(start, len(s)):
if predictor(s[i]):
return i
return -1
def find_all(s, sep=" \t\n"):
beg_of_nonsep = 0
while beg_of_nonsep < len(s):
beg_of_nonsep = find(s, beg_of_nonsep, lambda ch, sep_chs=sep: ch not in sep_chs)
if beg_of_nonsep == -1:
break
end_of_nonsep = find(s, beg_of_nonsep + 1, lambda ch, sep_chs=sep: ch in sep_chs)
if end_of_nonsep == -1:
end_of_nonsep = len(s)
yield (beg_of_nonsep, end_of_nonsep)
beg_of_nonsep = end_of_nonsep + 1
split = lambda s: [s[beg: end] for (beg, end) in find_all(s)]
print(split(""))
print(split(" \t\n"))
print(split(" \tssss\n"))
在解释器模式下逐行运行代码时,python3
给了我讨厌的错误:
Type "help", "copyright", "credits" or "license" for more information.
>>> def find(s, start, predictor):
... for i in range(start, len(s)):
... if predictor(s[i]):
... return i
... return -1
...
>>> def find_all(s, sep=" \t\n"):
... beg_of_nonsep = 0
... while beg_of_nonsep < len(s):
... beg_of_nonsep = find(s, beg_of_nonsep, lambda ch, sep_chs=sep: ch not in sep_chs)
... if beg_of_nonsep == -1:
... break
...
>>> end_of_nonsep = find(s, beg_of_nonsep + 1, lambda ch, sep_chs=sep: ch in sep_chs)
File "<stdin>", line 1
end_of_nonsep = find(s, beg_of_nonsep + 1, lambda ch, sep_chs=sep: ch in sep_chs)
^
IndentationError: unexpected indent
>>> if end_of_nonsep == -1:
File "<stdin>", line 1
if end_of_nonsep == -1:
^
IndentationError: unexpected indent
>>> end_of_nonsep = len(s)
File "<stdin>", line 1
end_of_nonsep = len(s)
^
IndentationError: unexpected indent
>>>
>>> yield (beg_of_nonsep, end_of_nonsep)
File "<stdin>", line 1
yield (beg_of_nonsep, end_of_nonsep)
^
IndentationError: unexpected indent
>>>
>>> beg_of_nonsep = end_of_nonsep + 1
File "<stdin>", line 1
beg_of_nonsep = end_of_nonsep + 1
^
IndentationError: unexpected indent
>>>
>>> split = lambda s: [s[beg: end] for (beg, end) in find_all(s)]
>>>
>>> print(split(""))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <lambda>
TypeError: 'NoneType' object is not iterable
>>> print(split(" \t\n"))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <lambda>
TypeError: 'NoneType' object is not iterable
>>> print(split(" \tssss\n"))
最后一个print
永远不会退出,直到我使用 ctrl c 停止它为止。
因此,我认为我的代码存在很多错误。
但是,当我使用python3 split.py
运行代码时,没有发生任何事情:
[]
[]
['ssss']
这让我很困惑。
要清楚一点,我实际上是在Debian 9.8和vim 8.1上使用vimcmdline。
我还使用pylint
到pymode
,它分割了认为多余的任何尾随空格。
当我尝试使用其内置的键绑定在打开的split.py
拆分中将python3
发送到tmux
时,发生了此问题。
我已经填写了issue,但我不禁要问为什么python3
会这样。
答案 0 :(得分:19)
这种行为对我来说并不奇怪。
Python使用缩进来确定代码块的开头和结尾。逻辑上的缩进在没有 缩进的第一行上结束。运行脚本时,空行将被忽略。而且,当运行脚本时,这意味着缩进以不缩进的行结尾或文件的结尾。
但是,此行为在命令行模式下不起作用,因为没有文件结尾。考虑以下脚本文件:
from somewhere import bar, do_something
for foo in bar:
do_something(foo)
在脚本中,文件末尾指示它现在应运行for循环。它知道没有更多要执行的了。但是在命令行模式下,命令行仍处于打开状态,您仍然可以编写更多内容。不知道下一行代码是在for循环内还是在for循环外。但是命令行不能只坐着等待下一行代码...您希望它现在执行...
因此,命令行以一种特定的区别进行操作。空行也将结束代码块。这样就可以了:
from somewhere import bar, do_something, do_something_else
for foo in bar:
do_something(foo)
do_something_else(foo)
但这是一个错误:
from somewhere import bar, do_something, do_something_else
for foo in bar:
do_something(foo)
do_something_else(foo)
因为您已经用空白行结束了for循环,因此无法添加到循环中。