繁体   English   中英

在 unix 下的 python 多处理中省略“if __name__ == '__main__'”语句是否安全?

[英]is it safe to leave out "if __name__ == '__main__'" statement for multiprocessing in python under unix?

我正在尝试在 python 中实现一个灵活的管道,我已经把它分成了几个模块。 这些模块中的每一个都可以用作独立工具,但有时它们也可能需要相互导入函数。 我已经将这些模块中的多个经常使用的通用简单函数放入一个“misc”模块中,该模块在需要时由所有其他模块导入。

现在,这些模块中的每一个都可能希望使用多处理(通常调用一些外部工具)并行运行某些功能。 因此,我创建了一个通用的“run_parallel”函数,它将函数列表和相应的参数作为参数,确定每个的优先级并相应地在它们上分配可用的内核,然后使用 multiprocessing 和 starmap() 并行运行这些函数。

现在我认为这个函数可以很好地放在“misc”模块中,并且可以在任何其他函数需要并行运行作业时导入。 但是,如果我遵循(显然)一般规则始终if __name__ == '__main__使用if __name__ == '__main__语句,则意味着我无法导入此函数并在多个模块中重用它。 我从来没有完全理解这个要求,但它似乎确实与 Windows 有关系,特别是? 我的管道只能在 unix 下工作。

这是否意味着我必须为我的每个模块单独实现这个“run_parallel”方法? 或者我可以安全地离开它,如果我的代码只打算在 linux/unix 环境下运行?

编辑:我现在意识到我完全误解了多处理教程和用法示例中此语句的用法。 我想,出于某种原因,在任何使用多处理功能的函数中也需要它(并且一直对为什么会这样感到困惑)。 但是在这些示例中,它们也只保护了调用该函数的示例代码部分,防止在每次导入时自动调用它(正如我所想的那样,根本不会阻止函数被导入)。 完全误会!

当您运行脚本或导入模块时,python 会执行在模块级别编写的所有代码。 在像这样的函数的情况下

def foo():
    pass

“执行”仅表示将新编译的函数对象分配给名为“foo”的变量。 这些东西不需要被if __name__ == "__main__":块保护。 您只需要关心执行操作的代码,例如调用foo()代码。

用于启动 python 程序的顶级脚本称为"__main__" 您导入的模块不称为"__main__"并且if __name__ == "__main__":块是没有意义的。 重要的是模块是导入安全的。 也就是说,导入一个模块而不做任何初始化之外的事情应该总是安全的。 模块的操作应该始终在从其他地方调用的函数或类中。

顶层脚本不同,它必须实际运行程序。 if __name__ == "__main__":用于使顶级脚本导入安全。 对于像 Unix 这样的分叉系统来说,这并不重要(至少对于多处理而言)。 但是 Windows 需要生成一个新进程并导入顶级脚本 - 并且该导入需要安全,它不能重新执行程序本身。

尽管您在 Unix 上不需要这种保护,但模块应该始终是导入安全的。 它也是顶级脚本的一个很好的纪律。 为什么在不需要时限制代码执行?

一个体面的脚本配方是

def main()
    do all the things
    return 0

if __name__ == "__main__":
    retcode = main()
    exit(retcode)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM