python 2.7.14 & 3.6 包导入的良好实践

python 2.7.14 & 3.6 good practice for package imports

我在使用最新的 python 版本(2 和 3)时遇到了一些问题,无法找到一种通用的导入方式。

关于我在 PyPI 上推送的包,没关系,因为我为包创建了一个子文件夹,然后在 __init__.py 中使用 package.module 进行导入。 我会在模块文件中做同样的事情。

除此之外,我还有一些我在项目之间共享的包(存储在我的 svn 服务器上),我在项目中导入为 svn external。

层次结构通常是这样设计的:

package:
 |- __init__.py
 |- module1.py
 |- module2.py
 |- ...

当我将其导入项目时,文件夹如下所示:

project:
 |- package:
     |- what's above
 |- app.py

我通常把包本身作为一个项目来开发,也就是说package是root。 当我将它导入到项目中时,它们变成了包,因此不再是根目录。

当在独立包项目中使用package.module.module时,当然,这不起作用。 在其他项目中使用 same as package 时,这几乎可以正常工作,但我在使用 Python 3.6 时遇到一些问题,告诉我某些名称未定义(直接从命令行启动时;但在 pycharm). 最后但同样重要的是,当使用 py2exe 制作可执行文件时(来自 Python 2.7),我得到了一些未定义的名称(类 等)异常,即使导入似乎没问题,因为没有引发此类异常;请注意,我能够看到 library.zip.

中有相关的 .pyc 文件

几个月前我没有经历过这些问题,旧版本的 python 2 和 python 3 都没有。

我打开这个问题是因为我在 Whosebug、python 文档(2 和 3)以及最近几天通过网络搜索了很多内容,但没有找到与整个问题真正相关的内容。

我的问题是,有没有人知道在 python 2 和 3 之间兼容的导入的良好做法,并且在包为 __main__ 时也可以工作?还有奖金,用py2exe打包还可以吗?

在某些时候,我为这些导入尝试了一些 try/except ImportError 块,但它有点混乱并且似乎不可靠。

非常感谢您的帮助!

提供了一些关于 __package__ 的线索:

Relative imports for the billionth time

我找到了一些更一致的解决方案以在导入前进行检查。

if __package__ is None or __package__ == '':
    from module1 import *
    from module2 import *
else:
    from .module1 import *
    from .module2 import *

如果您直接从文件本身 运行(比方说 module1),__package__ 就是 None。我仍然必须添加检查 __package__ == '',就好像 module1 导入 module2,包不是 None in module2.

在这种情况下,我更喜欢使用相对导入,即使不是真的推荐,因为当用作包时,包本身可以有任何名称而无需更改任何内容。

关于 __init__.py 文件,我只使用相对导入,因为它仅在从主应用程序作为包导入时使用:

import package
from package import xxx

这似乎很好地解决了 python 2.7.14 和 3.6 的导入问题,但仍然会导致 py2exe (2.7) 出现问题并且不会生成整个项目。