繁体   English   中英

在python中使用absolute_import并处理相对模块名称冲突

[英]Using absolute_import and handling relative module name conflicts in python

我真的希望这是一个简单的例子,让我想念复杂的Python2导入机制。 我有以下设置:

$> ls -ltr pypackage1 
total 3
-rw-r--r-- 1 pelson pelson   0 Aug 17 19:20 io.py
-rw-r--r-- 1 pelson pelson   0 Aug 17 19:20 __init__.py
-rw-r--r-- 1 pelson pelson  57 Aug 17 19:22 code.py
$> cat pypackage1/code.py 
from __future__ import absolute_import

import zipfile

即我只有一个带有空__init__.pyio.py的存根包,以及一个2行的code.py文件。

我可以导入pypackage1

$> python -c "import pypackage1.code"

但是我无法运行code.py文件:

$> python pypackage1/code.py
Traceback (most recent call last):
  File "pypackage1/code.py", line 3, in <module>
    import zipfile
  File "python2.7/zipfile.py", line 462, in <module>
    class ZipExtFile(io.BufferedIOBase):
AttributeError: 'module' object has no attribute 'BufferedIOBase'

显然问题与zipfile模块在内置io模块上拾取我的相对io模块有关,但我认为我from __future__ import absolute_import会修复它。

在此先感谢您的帮助,

这是正确的行为。 如果要修复错误,只需不要从包内运行。

当您运行包中的脚本时,python不会将该目录解释为包,从而将工作目录添加到PYTHONPATH 这就是为什么zipfile模块导入的io模块是你的io模块而不是标准库中的模块。

我建议在你的包之外(或在bin/scripts文件夹中)创建一个简单的启动器脚本,并启动它。 此脚本可以包含以下内容:

from pypackage1 import code

code.main()

另一种方法是告诉python解释器您要执行的文件是模块的一部分。 您可以使用-m命令行选项执行此操作。 在您的情况下,您将不得不这样做:

python -m pypackage1.code

请注意, -m的参数应该是模块名称 ,而不是文件名。

一种解决方案是将from __future__ import absolute_import放入zipfile.py模块中。 虽然您的模块使用绝对导入,但zipfile模块不是。

另一个选择是不从包目录运行。 您可能不应该从包目录中运行解释器。

文件结构:

test.py
mylib/__init__.py
mylib/__collections.py
mylib/collections.py
mylib/mymod.py

该解决方案允许:

  • test.py调用__builtin __。collections和mylib.collections
  • mymod.py调用上述,既当它运行作为库的一部分,并且当它被独立运行(例如,用于测试代码)

在test.py中:

from collections import deque
from mylib.collections import mydict

在mylib / __ init__.py中:

from __future__ import absolute_import
from . import collections
from . import mymod

在mylib / __ collections.py中:

class MyDict (dict):
    pass

在mylib / collections.py中:

from __collections import *

在mylib / mymod.py中:

from __future__ import absolute_import
from collections import deque
try:
    # Module running as part of mylib
    from .collections import MyDict
except ValueError:
    # Module running independently
    from __collections import MyDict

以上工作使用Python> = 2.5。 Python 3不需要来自__future__ import absolute_import的行'。

暂无
暂无

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

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