“样板” Python 代码?
Google 有一个 Python 教程,他们将样板代码描述为“不幸的”,并提供了以下示例:
#!/usr/bin/python
# import modules used here -- sys is a very standard one
import sys
# Gather our code in a main() function
def main():
print 'Hello there', sys.argv[1]
# Command line args are in sys.argv[1], sys.argv[2] ..
# sys.argv[0] is the script name itself and can be ignored
# Standard boilerplate to call the main() function to begin
# the program.
if __name__ == '__main__':
main()
现在,我听说样板代码被描述为“看似重复的代码,一次又一次地出现,以获得一些看起来像的结果”它应该更简单”(示例)。
无论如何,在 Python 中,上面示例中被视为“样板”代码的部分是:
if __name__ == '__main__':
main()
现在,我的问题如下:
1)Python 中的样板代码(如提供的示例)是否采用与我提供的定义相同的定义?如果是这样,为什么?
2)这段代码有必要吗?在我看来,无论是否有 main 方法,代码都会运行。是什么让使用此代码更好?是不是更好了?
3)我们为什么使用该代码以及它提供什么服务?
4)整个Python都会出现这种情况吗?还有“样板代码”的其他示例吗?
哦,还有一个题外话:你需要 import sys 才能在 Python 中使用命令行参数吗?如果它不存在,它如何处理此类争论?
Google has a Python tutorial, and they describe boilerplate code as "unfortunate" and provide this example:
#!/usr/bin/python
# import modules used here -- sys is a very standard one
import sys
# Gather our code in a main() function
def main():
print 'Hello there', sys.argv[1]
# Command line args are in sys.argv[1], sys.argv[2] ..
# sys.argv[0] is the script name itself and can be ignored
# Standard boilerplate to call the main() function to begin
# the program.
if __name__ == '__main__':
main()
Now, I've heard boilerplate code being described as "seemingly repetitive code that shows up again and again in order to get some result that seems like it ought to be much simpler" (example).
Anyways, in Python, the part considered "boilerplate" code of the example above was:
if __name__ == '__main__':
main()
Now, my questions are as follows:
1) Does boilerplate code in Python (like the example provided) take on the same definition as the definition I provided? If so, why?
2) Is this code even necessary? It seems to me like the code runs whether or not there's a main method. What makes using this code better? Is it even better?
3) Why do we use that code and what service does it provide?
4) Does this occur throughout Python? Are there other examples of "boilerplate code"?
Oh, and just an off topic question: do you need to import sys
to use command line arguments in Python? How does it handle such arguments if its not there?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
题外话:
如果您不编写代码来检查参数,它们将被忽略。
Off topic question:
If you don't write code to check the arguments, they are ignored.
在本例中,
if __name__ == "__main__":
块被称为样板文件的原因是它复制了许多其他语言中自动执行的功能。在 Java 或 C++ 等许多其他语言中,当您运行代码时,它会查找main()
方法并运行它,如果它不存在,甚至会抱怨。 Python 运行文件中的任何代码,因此您需要告诉它运行main()
方法;一个简单的替代方案是将运行main()
方法设置为默认功能。因此,
if __name__ == "__main__":
是一种常见的模式,可以更短。您没有理由不能做一些不同的事情,例如:这会很好;虽然我的例子有点傻,但你可以看到你可以在那里放任何你喜欢的东西。 Python 设计者选择这种行为而不是自动运行 main() 方法(该方法很可能不存在),大概是因为 Python 是一种“脚本”语言;因此您可以将一些命令直接写入文件中,运行它,然后执行您的命令。我个人更喜欢 Python 方式,因为它让初学者更容易开始使用 Python,而且拥有一种 Hello World 一行的语言总是很好。
The reason that the
if __name__ == "__main__":
block is called boilerplate in this case is that it replicates a functionality that is automatic in many other languages. In Java or C++, among many others, when you run your code it will look for amain()
method and run it, and even complain if it's not there. Python runs whatever code is in your file, so you need to tell it to run themain()
method; a simple alternative would be to make running themain()
method the default functionality.So,
if __name__ == "__main__":
is a common pattern that could be shorter. There's no reason you couldn't do something different, like:This will work just fine; although my example is a little silly, you can see that you can put whatever you like there. The Python designers chose this behavior over automatically running the
main()
method (which may well not exist), presumably because Python is a "scripting" language; so you can write some commands directly into a file, run it, and your commands execute. I personally prefer it the Python way because it makes starting up in Python easier for beginners, and it's always nice to have a language where Hello World is one line.您不需要为不打算成为较大项目一部分的一次性脚本添加
if __name__ == '__main__'
。请参阅此处了解详细说明。仅当您想单独运行该文件并将其作为模块与其他 python 文件一起包含时才需要它。如果您只想运行一个文件,则可以使用零样板:
并使用
$ python your_file.py
添加shebang 行
#!/usr/bin/python
并运行chmod +x print_one.py
让您能够使用./print_one 运行.py
You don't need to add a
if __name__ == '__main__'
for one off scripts that aren't intended to be a part of a larger project. See here for a great explanation. You only need it if you want to run the file by itself AND include it as a module along with other python files.If you just want to run one file, you can have zero boilerplate:
and run it with
$ python your_file.py
Adding the shebang line
#!/usr/bin/python
and runningchmod +x print_one.py
gets you the ability to run with./print_one.py
使用“if main”检查的原因是,您可以拥有一个在顶层运行其代码的某些部分的模块(以创建它导出的东西 - 常量、函数或类),而某些部分仅在执行时脚本(例如其功能的单元测试)。
后面的代码应该包装在函数中的原因是因为
main()
块的局部变量会泄漏到模块的作用域中。现在,另一种设计可能是,作为脚本执行的文件必须声明一个名为 __main__() 的函数,但这意味着向该语言添加一个新的魔术函数名称,而
__name__
机制已经存在。 (并且无法删除,因为每个模块都必须有一个__name__
,并且由于模块名称的分配方式,作为脚本执行的模块必须有一个“特殊”名称。)引入两个做同样的事情只是为了摆脱两行样板的机制 - 通常每个应用程序有两行样板 - 似乎不值得。The reason you use an "if main" check is so you can have a module that runs some part of its code at toplevel (to create the things – constants, functions, or classes – it exports), and some part only when executed as a script (e.g. unit tests for its functionality).
The reason the latter code should be wrapped in a function is because local variables of the
main()
block would leak into the module's scope.Now, an alternate design could be that a file executed as a script would have to declare a function named, say,
__main__()
, but that would mean adding a new magic function name to the language, while the__name__
mechanism is already there. (And couldn't be removed, because every module has to have a__name__
, and a module executed as a script has to have a "special" name because of how module names are assigned.) Introducing two mechanisms to do the same thing just to get rid of two lines of boilerplate – and usually two lines of boilerplate per application – just doesn't seem worth it.我来到此页面的主要原因是一个与您的问题 #3 类似的问题:
我阅读了这些解释,但仍然无法理解这个概念,尽管答案非常详细。在阅读这些解释后,我不得不弄乱一个小例子才能真正理解发生了什么。
这对我来说最终有意义:
希望这对某人有帮助
My main reason for coming to this page was a question similar to your question #3:
I read these explanations and still couldn't wrap my head around the concept, even though the answers were super detailed. I had to mess with a small example after reading those explanations to really understand what's going on.
This is what finally made sense to me:
Hopefully this helps someone
1) 主样板很常见,但不能再简单了
2) 如果没有样板,则不会调用
main()
3) 样板允许模块作为独立脚本使用,和 作为其他程序中的库
4) 它很常见。
doctest
是另一个。训练成为 Python 大师……祝论文好运! ;-)
1) main boilerplate is common, but cannot be any simpler
2)
main()
is not called without the boilerplate3) the boilerplate allows module usage both as a standalone script, and as a library in other programs
4) it’s very common.
doctest
is another one.Train to become a Python guru…and good luck with the thesis! ;-)
让我们花点时间看看调用
import sys
时发生了什么:sys
模块,argv
函数并运行它那么,这里发生了什么?
在其他地方编写的函数用于在当前程序范围内执行某些操作。以这种方式编程有很多好处。它将逻辑与实际劳动分开。
现在,就样板而言,有两个部分:
main
下定义,以及main
是否存在的调用部分您本质上是在
main
下编写程序,使用在定义main
(或其他地方)之前定义的所有函数,并让 Python 查找main
。Let’s take a moment to see what happened when you called
import sys
:sys
moduleargv
function and runs itSo, what’s happening here?
A function written elsewhere is being used to perform certain operations within the scope of the current program. Programming in this fashion has a lots of benefits. It separates the logic from actual labour.
Now, as far as the boilerplate is concerned, there are two parts:
main
, andmain
existsYou essentially write your program under
main
, using all the functions you defined just before definingmain
(or elsewhere), and let Python look formain
.我同样对教程中“样板代码”的含义感到困惑:这是否意味着可以在简单的脚本中避免此代码?或者是对强制使用这种语法的Python特性的批评?或者甚至邀请使用这个“样板”代码?
然而,我不知道,经过多年的 Python 编程,我至少清楚了不同语法的作用,即使我可能仍然不确定最好的方法是什么。
通常,您希望在脚本代码的末尾放置用于测试的代码或想要执行的代码,但这会产生一些影响/副作用:
python script.py
)或从 ipython shell 运行(< code>%run script.py),但无法从其他脚本运行它。避免在所有情况下执行以下代码的最基本机制是语法:
它使代码仅在脚本被调用或运行时才运行,避免了问题 1。另外两点仍然成立。
具有单独的
main()
函数的“样板”代码添加了进一步的步骤,也排除了上述第 2 点和第 3 点,因此,例如,您可以从不同的脚本调用多个测试,有时可以采取另一个级别(例如:多个函数,每个测试一个,因此可以从外部单独调用它们,以及调用所有测试函数的主函数,而不需要从外部知道它们是哪一个)。我补充说,除了其复杂性之外,我发现这种结构常常令人不满意的主要原因是,有时我想保留第 2 点,但如果将代码移至单独的函数,我就会失去这种可能性。
I am equally confused by what the tutorial means by "boilerplate code": does it mean that this code can be avoided in a simple script? Or it is a criticism towards Python features that force the use of this syntax? Or even an invitation to use this "boilerplate" code?
I don't know, however, after many years of Python programming, I have at least clear what the different syntaxes do, even if I am probably still not sure on what is the best way of doing it.
Often you want to put at the end of the script code for tests or code that want to execute, but this has some implications/side-effects:
python script.py
) or by running from ipython shell (%run script.py
), but there is no way to run it from other scripts.The most basic mechanism to avoid to execute following code in all conditions, is the syntax:
which makes the code run only if the script is called or run, avoiding problem 1. The other two points still hold.
The "boilerplate" code with a separate
main()
function, adds a further step, excluding also above points 2 and 3, so for example you can call a number of tests from different scripts, that sometimes can take another level (e.g.: a number of functions, one for each test, so they can be individually be called from outside, and a main that calls all test functions, without needs to know from outside which one they are).I add that the main reason I find this structures often unsatisfying, apart from its complexity, is that sometimes I would like to maintain point 2 and I lose this possibility if the code is moved to a separate function.