在Python中,模拟Perl的__END__最好的方法是什么?

32

我在想是否正确认为Python没有Perl的__END__的直接等价物?

print "Perl...\n";

__END__
End of code. I can put anything I want here.

有一个想法浮现在我脑海中,那就是使用三引号字符串。在Python中是否有更好的方法来实现这个?
print "Python..."

"""
End of code. I can put anything I want here.
"""

5
首先,为什么你需要它呢? - Tadeusz A. Kadłubowski
3
只是增加了一些便利性,没有其他更多的东西。当然,我可以将文件末尾注释掉。 - FMc
24
__END__ 很有用,我经常用它来作为长篇文档的结尾,或者在进行重大重构时,将一块代码块复制到末尾,同时我也会在我的“草稿”文件中经常使用它来测试小段代码。完成一个测试后,在顶部加上 __END__ ,接着开始下一个测试。这样一来,文件就保留了我已经处理的内容的历史记录。 - Eric Strom
9
有时我在测试中使用 __END__。使用情况是将代码脑海中倾泻出来,然后逐渐使其编译和通过测试。当顶部开始编译时,您将 __END__ 移到第二个或第三个测试用例,然后开始处理它们……然后重复该过程。如果您使用 git snapshot-watch,那么一切都已经“版本控制”了。__END__ 只是为了节省您的打字和更改。 - jrockway
3
我曾见过在想将数据包含在可执行文件中时使用 __END__。比如说,一个文件既是 Python 脚本又是 YAML 文件。我知道这被认为是一种不好的做法。然而,“为什么要这样做?”不是一个答案。 - Austin Richardson
显示剩余4条评论
7个回答

19

The

__END__
在Perl中,block的概念源自程序员需要处理来自外部世界的数据,并希望将其示例保留在程序本身中的时代。

很难想象吧。

例如,如果您有一个移动的目标(如硬件日志文件),其中包含由于固件更新而发生变异的消息,您希望比较该行的旧版本和新版本,或者保留与程序操作不严格相关的备注(“代码在每个月的第x天似乎很慢”),或者如上所述,运行程序的参考数据集。电信业是这种需求频繁出现的行业之一。

最后,Python类似邪教般的限制性似乎对其支持者的心态产生了真正而烦人的影响,如果您对问题的唯一回答是“为什么要做X,而不是Y”时,当Y并不像X那样有用,请保持沉默++。


14
当“只有一种方法可行”的时候,有时并没有任何方法可行。 - Joel Berger
8
Python是一种可爱的语言,但其设计哲学有时会越过创新与反应之间的界限。 - Micheal Lunny

8
您提出的三引号形式仍会创建Python字符串,而Perl解析器会简单地忽略__END__之后的任何内容。您不能编写以下代码:
"""
I can put anything in here...
Anything!
"""
import os
os.system("rm -rf /")

在我看来,评论更为合适。

#__END__
#Whatever I write here will be ignored
#Woohoo !

4
@Lott: 在 Perl 的 __END__ 标记之后,你可以放入任何内容,包括 Perl 代码、多个 __END__ 标记,以及其他任何内容。在 Python 中的三引号字符串中不能放置奇数个三引号(除非你记得进行转义)。如果你放置了偶数个三引号并加入一些 Python 代码,它将被执行。 - Tadeusz A. Kadłubowski
比之前版本的回答更清晰的例子。 - S.Lott
6
"Perl的解析器会简单地忽略__END__之后的任何内容。"其实不是这样的。DATA文件句柄可以访问__END__之后的所有内容。" - Alan Haggai Alavi
1
@AlanHaggaiAlavi DATA文件句柄没有使用Perl的解析器,所以确实是这样。一旦解析器看到__END____DATA__,它就完成了。它会记录位置并设置寻址点,以便DATA可以从那个点开始读取。 - DavidO

6

2
我经常使用__END__,原因有很多。我已经这样做了很长时间,通常会在exit('0');之前以及BEGIN {} / END{}程序中添加它。遗憾的是,Python没有相应的功能,但我只需在底部注释掉这些行:虽然有些冗余,但这就是你用一种方式统治所有语言所得到的结果。

2

嗯,sys.exit(0) 怎么样?(当然,假设你在它之前导入了 import sys

至于为什么有用,有时候我会坐下来对某个东西进行大量重写,并想要标记我的“到此为止”的地方。

通过暂时使用 sys.exit(0),我知道该点以下的任何内容都不会被执行,因此如果出现问题(例如服务器错误),我知道它必须在该点之上。

我比注释文件的其余部分稍微喜欢它一点,只是因为有更多的机会犯错误并取消注释某些内容(行首的杂乱按键),而且因为插入 1 行似乎比修改 X 行更好,后者将稍后需要被还原。

但是,这就是纠结的问题;注释也很好用... 当然,假设您的编辑器支持轻松注释掉一个区域;如果不支持,则完全可以使用 sys.exit(0)


2
sys.exit(0) 的问题在于它下面的所有内容仍然会被 Python 解释器解析,如果没有有效的语法,则会引发 SyntaxError - pts

0
这是我在Perl中使用__END__的一种方式(但不是唯一的方式),现在我正在进行Perl与Python3的比较分析,特别是正则表达式和最重要的是调试正则表达式。我首先编写我要测试的Perl版本。我在顶部放置了两个shebang,第一个启用了警告(-w),第二个调用了调试器(-wd),根据需要在它们之间切换。我为Python3添加了另外两个shebang,第二个使用Python的调试器(-m pdb)。为了运行Python3代码,我将Python3的shebang放在顶部,最顶部是我想要运行的Python版本,并使用vim的标记行功能进行块命令,在每个Perl行前面放置一个单独的#。要恢复到Perl,只需重新排列shebang并在vim中使用块命令取消注释一个#即可。非常好用!任何对比Perl和Python的人都可以试试看。
到目前为止,在我的分析中,我真的很喜欢Python3中的print(p.groupindex),其中p是一个编译过的正则表达式,用于检查组名和数字之间的映射关系。而在Perl中,我更喜欢__END__和正则表达式调试模块。此外,有mod_perl但不再有mod_python,并且可能永远也不会再有了。我对面向对象编程不太感兴趣,更喜欢函数式编程,两者都适用。当然,如果我对面向对象编程感兴趣,我会选择Python3,因为它具有清晰的多重继承模型。只是个人意见,在使用Perl超过30年后。老实说,要真正熟练掌握Perl花费了很长时间,但学习Python更快,但这可能是因为我真的精通Perl和C。如常,你的体验可能会有所不同...

-5

Python没有直接等价的功能。

你为什么想要它?当有更一致的方法,比如将文本作为注释放在结尾处时(这是我们在Python源文件中包含任意文本的方式。三引号字符串用于创建多行字符串,而不是非代码相关的文本),它听起来并不像一个真正好的东西。

你的编辑器应该能够轻松地让你使用多行注释。


3
有时在编写代码时,注释掉尚未工作的代码段并让Perl假装该代码不存在是很有用的。 - Brad Gilbert
14
仅仅因为你想不到使用它的理由,并不意味着它没有用途。 - Brad Gilbert
1
@Brad,注释代码可能非常危险,并且通常表明某人没有正确地使用他们的编辑器或版本控制系统。如果有人确实希望注释掉一大段代码,任何合理的文本编辑器都可以轻松完成。多行字符串所做的不是注释,我见过这种情况真正给像他们写代码的人带来麻烦。 - Mike Graham
你会注意到我并没有声称没有原因;事实上,我要求了原因。只有通过找到真正的问题,我们才能得到最优解决方案。 - Mike Graham
4
为什么我想要这个?我想要它是因为在程序中拥有一段文本块来记录程序的使用(它不值得有自己的文件),而且我似乎无法找到一个好的方法来告诉解析器忽略所有不打算与之交互的字符。__ END __ 关键字或者在可达的 exit() 调用上终止进一步语法扫描都会很有用。 - Michael J. Evans

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