簡體   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