您现在的位置是:首页 > 文章详情

木兰编程语言不同运行版本的 Python sys.path 差异小结

日期:2020-12-30点击:476

上文中的两个问题之一,是发布到 PyPI 的版本在运行时有个测试未通过:测试/引用/引用本地包内py.ul,而开发版和木兰原始可执行文件是通过的。

由于这是第一次发觉 PyPI 发布版本的行为差异,于是优先研究。

问题描述

测试源码如下:

 using test.package.module_py test.package.module_py.talk()

在项目根目录下(后文如无特别说明,命令运行都在根目录下),有如下测试包结构:

  • test
    • package
      • module_py.py
  • test_module_py.py <--- 该模块在根目录下

开发版如下运行测试无误:

 $ python3 -m 木兰 测试/引用/引用本地包内py.ul 

但如果安装在 PyPI 的发布版,再如下运行相同测试用例则报错(见此 issue):

 $ 木兰 测试/引用/引用本地包内py.ul 没找到模块:‘test.package’ 调用层级如下 见第1行:using test.package.module_py 

但是,发布版如下引用当前目录下的模块并无问题:

 using test_module_py test_module_py.talk()

为何?

调查过程

由于木兰原始可执行文件运行该测试无误,于是首先对木兰重现项目用 PyInstaller 生成(参考前文)exe 文件进行测试,引用并无问题。

由于无头绪,建立最简项目重现问题,再次确认当前运行目录需添加到 sys.path 才能引用当前目录下的模块 test_module_py(在此前的 commit 中实现)。接下去围绕 sys.path 做一系列测试。

期间试着将 test 目录改名为 tes,结果引用成功。又直接使用__import__('test'),才发现在 Python3 的包路径中,原就存在一个 test 包。

结论

sys.path 在不同运行版本的区别如下:

  • PyPI 发布版:虽然添加了运行当前目录到 sys.path,但位于末尾。在 sys.path 中更靠前的路径中包含 Python3 的包路径,其中恰好存在其他 test 包,而且该包中没有 package 子目录,因而报错。
  • exe 发布版(用 PyInstaller 生成):sys.path 中不包含 Python3 的包路径,因而不会认错 test 包。
  • 开发版:运行的当前目录位于 sys.path 第一个。sys.path 中虽也包含 Python3 的包路径,但由于顺序靠后,并不起作用,因而不认错 test 包。

由此来看重现项目两种发布版的优劣势:

  • PyPI 发布版:由于自带 Python3 包路径,那么只要是当前 Python3 环境下可用的包,木兰即可引用。副效应就是万一碰到上面这样的同名包,会优先引用 Python3 自带包,而 Python 的行为是优先引用自定义包。
  • exe 发布版:由于不带 Python3 包路径,木兰将不能引用 Python3 环境下安装的包。当然也就没有同名包的优先问题。但如果用户自行配置了环境变量,使得系统路径中包含 Python3 的包路径,是否会有同样问题尚待确认。
 
原文链接:https://www.oschina.net/news/125009
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章