【问题标题】:Purpose of some boilerplate code in __main__.py__main__.py 中一些样板代码的用途
【发布时间】:2016-07-17 03:41:38
【问题描述】:

我在 __main__.py 的几个 Python 项目中看到了以下代码。有人能解释一下目的吗?当然它会将包含__main__.py 的目录放在sys.path 的头部,但是为什么呢?以及为什么要测试(__package__ is None and not hasattr(sys, 'frozen')?另外,在sys.path.insert 中,为什么os.path.dirname 被调用了两次?

import sys

if __package__ is None and not hasattr(sys, 'frozen'):
    # direct call of __main__.py
    import os.path
    path = os.path.realpath(os.path.abspath(__file__))
    sys.path.insert(0, os.path.dirname(os.path.dirname(path)))

【问题讨论】:

  • edit 现在使用适当的文件名
  • 这是设置 Python 项目以确保设置正确的路径,从我假设是脚本目录到库目录,如果他们不使用 Python 打包。
  • 感谢 cricket 编辑我的双下划线名称。以后我会记得使用反引号来转义格式字符。

标签: python main pythonpath


【解决方案1】:

os.path.dirname(os.path.dirname(path)) - 获取祖父目录(包含给定path 变量目录的目录);这被添加到系统的PATH 变量中。

os.path.realpath(os.path.abspath(__file__)) - 获取运行文件绝对路径的realpath(解析符号链接)。

通过这种方法,项目现在可以执行包含在该祖父目录中的二进制文件,而无需为二进制可执行文件添加前缀。

旁注:如果没有您在哪里看到此代码的上下文,很难给出更多关于为什么使用它的答案。

【讨论】:

  • 技术上它有点多余,因为 realpath 和 abspath 应该执行类似的功能。事实上,posixpath 模块的 realpath 调用 abspath,而ntpath 的 realpath 是 abspath 的别名。否则,+1。
  • @AlexanderHuszagh 当然,我只是在解释功能,而不是实现
  • 公平。虽然至于为什么,很多脚本使用“脚本”目录(可以是任何名称),然后有一个库目录。然后使用两个目录名将解析到主目录,因此可以在没有标准 Python 打包的情况下解析从库中导入的内容。它非常适合独立应用程序,可以通过 setuptools 安装或不安装。 (不是 100%,但这是一个很常见的用例)。
  • 啊,谢谢,我没有意识到如果给定一个目录 os.path.dirname 会去掉最后一个目录名(我应该查一下!),所以它的嵌套使用得到了父目录的父目录,而不仅仅是一个多余的调用。
【解决方案2】:

__package__ 的测试让代码在使用 python __main__.pypython package/ 之类的命令(直接命名文件或命名包文件夹的路径)运行 package/__main__.py 时运行,而不是更正常的方式运行包python -m package 的主模块。另一项检查(针对sys.frozen)测试包是否已与py2exe 之类的内容一起打包到单个文件中,而不是在普通文件系统中。

代码所做的是将包的父文件夹放入sys.path。也就是说,如果__main__.py 位于/some/path/to/package/__main__.py,代码会将/some/path/to 放入sys.path。每次调用dirname 都会从路径右侧剥离一项("/some/path/to/package/__main__.py" => "/some/path/to/package" => "/some/path/to")。

【讨论】:

  • 谢谢。现在测试是有意义的。我没有想到您可能会以不同的方式启动__main__.py
  • 我可以问一个相关的问题:如果你已经将你的应用程序构建为一个可执行包,也就是说,如果它有一个__main__.py__init__.py,那么在__main__.py 你将拥有规范的“if name__== '__main'”,您实际启动应用程序的位置。我不会在那儿放很多代码,也许只有一行来调用“真正的”主函数。但是你会在__main__.py 中定义这个真正的主函数,还是为它创建一个新的模块文件?显然你可以把它放在你想要的任何地方,但是关于真正的 main 函数的位置,什么被认为是“最佳实践”?
猜你喜欢
  • 2011-05-01
  • 2018-08-30
  • 2011-12-15
  • 2015-09-28
  • 1970-01-01
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多