簡體   English   中英

Python導入,路徑,目錄和模塊

[英]Python Imports, Paths, Directories & Modules

首先讓我說我已經對過去一周的過程進行了廣泛的研究,但還沒有找到這些問題的實際答案 - 只是一些模糊的答案並沒有真正解釋發生了什么。 如果這只是因為我錯過了我想要的東西,我很抱歉 - 請指出我正確的方向。

我的目錄結構是:

TestProject/
    runtest*
    testpackage/
        __init__.py
        testmod.py
        testmod2.py
        testsubs/
            testsubmod.py

幾個筆記:

  • 我在Ubuntu上使用python2.7
  • 我正在測試bpython
  • 我正在從特定目錄運行bpython來測試導入行為的方式
  • 我正在嘗試遵循最佳做法。
  • 這個軟件包沒有安裝,它在一個隨機的dev目錄中
  • 該目錄不在pythonpath中
  • 我在包目錄中有一個init .py
  • 嵌套目錄中沒有init .py文件
  • init .py文件為空
  • testpackage / testmod.py包含TestModClass
  • testpackage / testsubs / testsubmod.py包含TestSubModClass

我觀察到的事情:

  • 當我從TestProject / import testpackage運行bpython時
    • 這不會導入testpackage.testmod
    • 我根本無法訪問testpackage.testmod
  • 當我從TestProject / import運行bpython時, testpackage.testmod失敗了
  • 當我從testProject運行bpython / 從testpackage導入testmod工作
  • 我可以向init .py添加代碼以顯式導入testmod.py,但不能testubs / testmod.py
    • 我不認為這是正確的方法,如果用戶不想導入該模塊怎么辦?
  • 從testmod.py我可以導入testmod2,但不能導入testpackage.testmod2
    • 這樣做很好,我可以使用STL或扭曲的名稱(例如testpackage.logging)命名我自己的模塊,而不會導致錯誤(很糟糕的是必須命名我自己的模塊廢話,如customerlogging,而不僅僅是mypackage。日志記錄)

問題是:

  1. python路徑中存在的包和模塊上的導入與您嘗試從當前目錄導入時的python處理方式不同嗎?
  2. 為什么不導入testpackage讓我訪問testpackage.testmod? 當我導入操作系統時,我可以訪問os.path(etc)。
  3. 使用包,我應該堅持在基目錄中使用單個init .py,還是應該將它們嵌套在后續目錄中?
  4. 如何導入指定包名稱的模塊? 來自testmod.py的IE,我想導入testpackage.testmod2而不僅僅是testmod2。
  5. 從subsubs目錄導入子模塊的正確方法是什么?
    1. 我看到的唯一解決方案是將該目錄從init .py附加到pythonpath,但我不知道這是否正確。

提前致謝。

首先,您將在The Python Tutorial的第6部分找到所需的所有信息。


(1)python路徑中存在的包和模塊上的python與您嘗試從當前目錄導入時的處理方式不同嗎?

不,它沒有。 實際上,Python在導入模塊時總是搜索sys.path 僅找到當前目錄中的模塊,因為sys.path包含帶有空字符串的條目,表示當前目錄。


(2)為什么不import testpackage讓我訪問testpackage.testmod 當我導入os ,我可以訪問os.path (etc)。

為了提高效率, import testpackage只加載testpackage/__init__.py 如果你需要testpackage.testmod ,你必須明確地導入它:

import testpackage   # Just imports testpackage, not testpackage.testmod!
import testpackage.testmod   # Import *both* testpackage and testpackage.testmod!

如果你總是想導出testmod ,在__init__.py導入它,這就是osos/__init__.py )所做的。 這樣,如果導入testpackagetestpackage.testmod總是隱含可用。

由於Python是跨平台的,因此實際上無法在目錄中一致地自動加載模塊,因為某些文件系統不區分大小寫(Windows!)。 Python不知道是否將os/path.py加載為os.pathos.Path等。


(3)對於一個包,我應該堅持在基目錄中使用單個__init__.py ,還是應該將它們嵌套在后續目錄中?

每個子包總是需要__init__.py 有關於放棄這一要求的討論,但決定保持原樣。


(4)如何導入指定包名稱的模塊? 來自testmod.py IE,我想導入testpackage.testmod2而不僅僅是testmod2

這應該工作。 只需確保從頂級目錄運行代碼。 如果當前目錄是testpackage ,則testmod不知道它在包中。

但首選的方法是使用相對的包內導入:

from . import testmod2

如果存在名為testmod2的全局模塊,則可以防止名稱沖突,並且可以使用包中的已知模塊的名稱而不會出現問題。


(5)從subsubs目錄導入子模塊的正確方法是什么? 我看到的唯一解決方案是將該目錄從__init__.py附加到pythonpath,但我不知道這是否正確。

不,不要那樣做! 永遠不要把一個目錄下sys.path當它的一個父目錄已經在sys.path 這可能導致您的模塊加載兩次,這是一件壞事!

通常,您應該能夠使用絕對或相對導入從子包加載模塊:

import testpackage.testsubs.testsubmod
from testpackage.testsubs import testsubmod
from .testsubs import testsubmod

只需確保在testsubs/創建__init__.py

  1. 不。當前目錄剛剛添加到PYTHONPATH。
  2. 首先,你需要一個__init__.py。 其次,os.path是因為os正在導入os.path。
  3. 每個目錄中需要__init__.py,也包含testpackage目錄。
  4. 在包的__init__.py中,導入您要提供的模塊。
  5. 來自sub1.sub2 import子模塊
    1. 不,如果最頂層的目錄在PYTHONPATH上,並且這個和子目錄有__init__.py,那么您只需要從任何子目錄導入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM