Python 中有一个 Main 类有什么意义?

发布于 2025-01-13 08:26:45 字数 1432 浏览 1 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

何止钟意 2025-01-20 08:26:45

没有意义。您正在查看由从未费心学习 Python 习惯用法的 Java 程序员编写的代码。

惯用的Python脚本将有一个main函数,但没有一些包装它的顶级类。标准结构是:

#!/usr/bin/env python3

# imports here

# Globals (usually constants) here

# Non-main functions & classes (possibly for use when imported as a module) here

def main():
    # Parse arguments and do main script things here

if __name__ == '__main__':
    main()

编写您正在查看的代码的 Java 开发人员习惯于 Java,其中一切都必须是类的一部分(就此而言,给定的源文件可以具有只有一个公共顶级类,因此 Java 程序的入口点通常单独存在,并且依赖于其他文件中的实用程序类)。在Python中,模块本身是可执行的。即使您需要一些类似类的行为,模块本身的行为也类似于最基本的用例(例如,全局变量处理实例属性的工作)。关于这样一个类的唯一可能的用途是,如果您要并行运行入口点的多个执行,并希望它们每个都有自己单独的“全局变量”,但是您需要经历的扭曲,在你想要这样做,但更简单的功能不能充分处理这项工作,这将是痛苦的。

从技术上讲,对于从不作为模块导入的简单脚本,您不需要 mainif __name__ == '__main__': ,但最好进入习惯,因为有些东西,例如在非fork模式下运行的multiprocessing模块,假设可以导入主模块来建立与父进程匹配的状态;如果您没有正确保护“脚本”行为,它们将在每个工作人员中重新运行。


严格来说,main 函数的内容不需要在函数中;您可以将它们内联到 if __name__ == '__main__': 块中。将它们放在专用函数中的优点是:

  1. “脚本”内容和“模块”内容之间的命名空间分离。如果您不将脚本行为包装在函数中,则会污染全局命名空间,并且您可能会意外地依赖这些实用函数的全局名称。当您稍后尝试将模块导入到另一个脚本中时,这些变量未定义,并且实用程序函数不起作用
  2. 性能:在全局范围内运行时,所有变量都是全局范围的,这在 CPython 上意味着加载或存储对他们来说涉及一个dict操作。在具有本地作用域变量的函数内执行相同的工作可将其简化为 C 级数组查找。虽然两者都是平均情况 O(1),但 dict 操作比直接从 C 数组加载具有更大的可变性和更高的固定开销。

There is no point. You're looking at code written by a Java programmer who never bothered to learn Python idioms.

Idiomatic Python scripts will have a main function, but not some top-level class wrapping it. A standard structure would be:

#!/usr/bin/env python3

# imports here

# Globals (usually constants) here

# Non-main functions & classes (possibly for use when imported as a module) here

def main():
    # Parse arguments and do main script things here

if __name__ == '__main__':
    main()

The Java developer who wrote the code you're looking at is used to Java, where everything must be part of a class (and for that matter, a given source file can have only one public top-level class, so the entry point for a Java program typically sits alone, and relies on utility classes from other files). In Python, the module itself it executable. Even if you needed some class-like behaviors, the module itself acts like one for most basic use cases (e.g. global variables handle the job of instance attributes). About the only conceivable use for such a class would be if you were going to run several executions of the entry point in parallel and wanted them each to have their own separate "globals", but the contortions you'd need to go through, in which you want to do that and simpler functions don't handle the job adequately, would be painful.

Technically, you don't need main or if __name__ == '__main__': for simple scripts that are never imported as modules, but it's a good idea to get in the habit, because some things, e.g. the multiprocessing module running in non-fork mode, assume the main module can be imported to establish state matching the parent process; if you haven't guarded the "script" behaviors properly, they'll get rerun in every worker.


Strictly speaking, the contents of the main function don't need to be in a function; you could just inline them within the if __name__ == '__main__': block. The advantages to putting them in a dedicated function are:

  1. Namespace separation between "script" stuff and "module" stuff. If you don't wrap the script behaviors in a function, you pollute the global namespace, and you may accidentally rely on those global names for the utility functions. When you later try to import the module into another script, those variables aren't defined, and the utility functions don't work
  2. Performance: When run at global scope, all variables are globally scoped, which, on CPython, means loading or storing to them involves a dict operation. Doing the same work inside a function with locally scoped variables reduces it to a C level array lookup. While both are average case O(1), dict operations have greater variability and higher fixed overhead than directly loading from a C array.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文