【问题标题】:Python 3 package module conflicts with standard modulePython 3 包模块与标准模块冲突
【发布时间】:2012-11-04 07:53:28
【问题描述】:

我最近决定升级到 python 3,并开始转换我的一些脚本。我在使用名为 io 的模块的脚本中遇到了问题 - 在 python 2 中,这非常好,但是在 python 3 中,io 是文件的标准模块。我发现this old question 大约是相同类型的问题,但这似乎与python 2 相关。我有相反的问题 - 给定两个文件,main.pyio.py 在顶级包中,import iomain.py 将导入标准的 io 模块,而不是本地模块。 from __future__ import absolute_imports 没有帮助,from . import io 和相关尝试按预期失败(我从来不明白 - python 真的不知道顶级包在哪里?)。重命名显然是一种解决方案,但如果可能的话,我想避免它。是否有一些解决模块名称冲突的python 3标准方法?

【问题讨论】:

  • 这里有一个类似的问题和答案-stackoverflow.com/questions/1224741/…
  • 是的,我链接了那个:“我发现 this old question 也有类似的问题,但这似乎与 python 2 有关。”
  • 在 Python3 中,绝对导入是默认的。所以:-from .base import BaseThing 领先。说“从模块目录导入基础”;换句话说,.base 映射到 ./base.py
  • from .io import * 适合您的情况。
  • from .io import * 抛出 SystemError: Parent module '' not loaded, cannot perform relative import 因为这两个模块都在顶级包中。像from . import io 这样的相关表单会抛出同样的错误。

标签: python python-3.x python-2.x


【解决方案1】:

这是我的答案:-

我的目录结构:-

calvin$ tree /Users/calvin/work/learn3/
/Users/calvin/work/learn3/
└── myspecialpackage
    ├── __init__.py
    ├── __init__.pyc
    ├── io.py
    ├── io.pyc
    └── main.py

__init__.py 是一个空文件。

io.py 是你的自定义模块,它与 python3 的 io 模块冲突。

main.py 包含这一堆示例代码:-

import os
import sys

# These two lines are not needed you are installing the `myspecialpackage` via pip/pypi and as setup.py script places "myspecialpackage" and all its contents in your python site-packages, which is already in PYTHONPATH.
our_package_root = os.path.dirname(os.path.realpath(__file__))
sys.path.append(our_package_root)

from myspecialpackage import io
print(io.__file__)

导入的io 模块将是您的io.py 中的一个,而不是python3 的模块。

作为奖励,使用这种方法将允许我们拥有您的自定义 io.py 以及 python3 的 io 模块(如果您希望拥有自己的蛋糕并吃掉它 ;-))。您可以像这样解除命名空间 io 的使用冲突:-

from myspecialpackage import io as my_special_io
print(my_special_io.__file__)

import io
print(io.__file__)

运行main.py 然后会给你:-

In [3]: run myspecialpackage/main.py
/Users/calvin/work/learn3/myspecialpackage
./myspecialpackage/io.py
/Users/calvin/.virtualenvs/learn3/bin/../lib/python3.3/io.py

注意我上面对

的评论
our_package_root = os.path.dirname(os.path.realpath(__file__))
sys.path.append(our_package_root)

【讨论】:

  • 这也不起作用-似乎与建议sys.path.insert(1, '/path/to/package')的另一个答案(作者删除了?)有关。是否有可能我的安装配置错误?我还注意到您使用的是 2.7,而我使用的是 3.3。这有什么显着改变吗?
  • 这不重要。我正在使用 iPython shell 进行一些仍然使用 python2 的打印输出。 Python 普通 shell 工作正常。
  • 你确定你完全按照我上面描述的目录结构吗?
  • 唯一的区别是__init__.py没有对应的.pyc。不过,这不应该改变任何事情。
  • 更改 sys.path 与 OP 的问题无关,通过将模块放入 myspecialpackage 并使用绝对导入来解决该问题。顺便说一句,learn3 应该在 sys.path 中,而不是 myspecialpackage 目录中。 python -mmyspecialpackage.main 应该可以在不修改 main.py 中的 sys.path 的情况下工作。
猜你喜欢
  • 1970-01-01
  • 2011-08-21
  • 1970-01-01
  • 2017-07-10
  • 2013-04-12
  • 1970-01-01
  • 2017-06-27
相关资源
最近更新 更多