6

我真的希望这是我错过了复杂的 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__.pyandio.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会解决这个问题。

提前感谢您的帮助,

4

3 回答 3

8

这是正确的行为。如果您想修复错误,请不要从包内部运行。

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

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

from pypackage1 import code

code.main()

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

python -m pypackage1.code

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

于 2012-08-17T21:28:40.387 回答
2

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

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

于 2012-08-17T20:47:14.800 回答
1

文件结构:

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 不需要'from __future__ import absolute_import' 行。

于 2013-10-09T11:04:57.510 回答