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



我遇到过一些例子,人们使用Main类,然后在Main类内部编写实例化其他类并调用其函数的逻辑。

示例:

# ^^^ code containing class OtherClass() ^^^
class Main:
def __init__(self):
print("n **** Main class from which we call other classes **** n")
other_object = OtherClass()

self.plot_graphs(other_object)

def plot_graphs(self, other_object):
# plot stuff
pass
# vvv code containing main code which instantiates main = Main() vvv

在实现这一点时,我看到了警告,即Main类(如plot_graphs(中的所有方法/函数都是/应该是静态的。从这个意义上说,如果您可以去掉Main之外的那些函数,那么为什么要有Main类呢?

我知道有一些变通方法,比如添加像@staticmethod这样的装饰器或像#noinspection PyMethodMayBeStatic这样的宏。但这让我想知道,如果你不改变Main类的属性,那么它是否是Python的。

没有意义。您看到的是一位Java程序员编写的代码,他从未费心学习Python习惯用法

Idiomatic 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),但与直接从C数组加载相比,dict操作具有更大的可变性和更高的固定开销

相关内容

最新更新