欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python相對包導(dǎo)入報“Attempted?relative?import?in?non-package”錯誤問題解決

 更新時間:2023年02月27日 14:58:36   作者:小舔哥  
這篇文章主要介紹了python相對包導(dǎo)入報“Attempted?relative?import?in?non-package”錯誤,本文要在原理上解決?python當中相對包導(dǎo)入出現(xiàn)的問題,需要的朋友可以參考下

文章是從stackoverflow翻譯過來的,原文地址:Relative imports for the billionth time

本文要在原理上解決 python當中相對包導(dǎo)入出現(xiàn)的問題。

問題描述

在win7、32位的電腦上,運行python2.7.3,經(jīng)常會出現(xiàn)"Attempted relative import in non-package"這樣的問題。

為了解決這個問題,我(提問的人)搜索了以下網(wǎng)站,當然還有更多的網(wǎng)站

我根據(jù)pep-0328建立了以下的目錄結(jié)構(gòu)

package/

    __init__.py

        subpackage1/

            __init__.py

            moduleX.py

            moduleY.py

        subpackage2/

            __init__.py

            moduleZ.py

        moduleA.py

而且按照這個目錄當中的要求,建立了了spam(moduleY.py中)和eggs(moduleZ.py中)函數(shù),現(xiàn)在想要在moduleX.py當中調(diào)用別的函數(shù)或模塊。很顯然,當我運行的時候,并沒有成功。

上面的第四個URL當中有如下信息,這個答案比較接近真相,但是其中的有些概念還是很難理解:

相對導(dǎo)入使用模塊的名稱屬性來決定模塊在包層次結(jié)構(gòu)中的位置,如果模塊的名稱不包含任何包信息(例如:被設(shè)置成‘main’),那么相對導(dǎo)入則被解析為最頂層的位置,不管這個時候這個模塊實際上位于文件系統(tǒng)中的什么位置。

所以,如何讓我運行的python程序不再返回"Attempted relative import in non-package"問題?python為什么會報這個錯誤?這里的‘non-package’是什么意思?為什么以及如何去定義一個‘package’?同時解釋一下-m選項?

回答:

什么是腳本?什么是模塊?(script vs module)

直接運行一個文件和在別的文件中導(dǎo)入這個文件是有很大區(qū)別的,僅僅知道一個文件在目錄中的位置并不意味著python程序就認為它在什么位置。這是由python用何種方式加載(運行或者導(dǎo)入.run or import)這個文件來決定的。

python有兩種加載文件的方法:一種是作為頂層的腳本,另一種是當做模塊。如果你直接執(zhí)行這個程序,那么這個文件就被當做是頂層腳本來執(zhí)行了,在命令行里面輸入 python myfile.py 就是這個情況。如果你輸入python -m myfile.py或者在其他的文件當中使用import來導(dǎo)入這個文件的時候,它就被當做模塊來導(dǎo)入。在同一時間里,只有一個頂層腳本,頂層腳本可以這樣解釋:它是一個能夠讓你的程序從這里開始的python文件。

【文件(file)是一種無區(qū)別的叫法,如何運行和處理這個文件,決定了它的性質(zhì)。直接從這個文件運行,那么這個文件就叫做腳本。導(dǎo)入這個文件,那么這個文件就是模塊(module)。另外,一個包(package)是一個包含有__init__.py的文件夾,下面會用到】

命名(naming)

當一個文件被加載進來,它就有一個名稱(這個名稱存儲在__name__屬性當中)。如果這個文件被當做一個頂層腳本來進行加載,那么它的名字就是__main__。如果它被當做一個模塊加載,那么它的名稱就是文件名稱,加上它所在的包名,以及所有的頂層的包名,這些名稱中間是用點號隔開的。

比如下面的例子

package/

    __init__.py

    subpackage1/

        __init__.py

        moduleX.py
    moduleA.py

比如你導(dǎo)入moduleX(from package.subpackag1 import moduleX),它的名稱就package.subpackage1.mouleX。如果你導(dǎo)入moduleA的時候(from package import moduleA),它的名稱就是package.moudleA。

(注:這里是使用包導(dǎo)入,即把package以及里面的所有文件看做一個包,導(dǎo)入的時候使用from ... import ...的形式來進行,我們調(diào)用第三方包的時候就是這種情況),

但是,當你直接從命令行里面運行moduleX的時候,他的名稱則被替換為__main__。如果你直接從命令行運行moduleA,它的名稱也是__main__。當一個模塊被當做一個頂層腳本來執(zhí)行的時候,它原來的名稱則會被__main__取代。

不通過包導(dǎo)入訪問一個模塊

這里有一個額外的問題:模塊的名稱取決于從它所在的目錄中直接導(dǎo)入的,還是通過包導(dǎo)入的。這種情況只有在該包中運行python文件,并且試圖導(dǎo)入這個包當中的其它文件的時候才有意義。(可以發(fā)現(xiàn),上面的介紹的包導(dǎo)入總是在外面來訪問一個模塊)

舉個例子,如果你在package/subpackage1目錄當中打開python解釋器,然后輸入import moduleX,那么moduleX的名稱就是moduleX,而不是package.subpackage1.moduleX。這是因為python把當前的目錄添加到了搜索路徑上面。如果它發(fā)現(xiàn)被包含的模塊在當前的目錄當中,它將不知道該目錄也是模塊的一部分,包的信息不會出現(xiàn)在模塊名稱當中。

當你直接運行python解釋器(比如cmd里面輸入python,然后進入python解釋器,或者使用ipython)。在這種情況下,這種交互式的終端的名稱是__main__。

現(xiàn)在,你的問題有了一個關(guān)鍵性的答案:如果一個模塊名稱當中沒有點號,那么它就不會被當做是一個包。不管這個文件在磁盤的什么位置。所有關(guān)鍵在于,它的名稱是什么,而這個名稱取決于你如何加載它。

那么現(xiàn)在看一下你在其他的URL當中的引用的這句話:

相對導(dǎo)入使用模塊的名稱屬性來決定模塊在包層次結(jié)構(gòu)中的位置,如果模塊的名稱不包含任何包信息(例如:被設(shè)置成‘main’),那么相對導(dǎo)入則被解析為最頂層的位置,不管這個時候這個模塊實際上位于文件系統(tǒng)中的什么位置。

相對導(dǎo)入...

相對導(dǎo)入使用模塊的名稱去決定它在一個包中的位置。當你使用了一個像這樣的相對導(dǎo)入:from .. import foo,這里的點號表明在包的層次結(jié)構(gòu)當中上升幾個層級。比如,現(xiàn)在模塊的名稱是package.subpackage1.moudleX,然后..moduleA中的兩個點號表示的是上升兩個層級,到達package,然后package和moduleA結(jié)合,最終成為package.moduleA。要讓from .. import這樣的相對導(dǎo)入正常工作,模塊的名稱中至少要有和語句中相對應(yīng)的“點”的數(shù)量。

...只能用在相對導(dǎo)入當使用

如果你的模塊的名稱是__main__,那么它就不被認為是在一個包當中,因為它的名稱當中不含有“點”,所以你不能在它的里面使用from .. import。如果你使用了這個語句,那么程序就會報“relative-import in non-package"錯誤。

腳本不能包含相對導(dǎo)入:

當你直接運行moduleX或者是在命令行終端里運行程序的時候,這個時候模塊的名稱都是__main__,這就表明你不能使用相對導(dǎo)入。因為他們的名稱表示他們并不在一個包當中。注:當你運行的python目錄就是你模塊所在的目錄的時候,上面這種情況也會發(fā)生,這種情況下python過早的尋找當前目錄的模塊,并沒有認為他們也是包的一部分。

當你運行交互式的解釋器的時候,交互式進程的名稱永遠是__main__,因此你不能在交互式進程當中使用相對導(dǎo)入。相對導(dǎo)入只能在模塊文件當中使用。

兩個解決方法:

1:如果你想直接運行moduleX,但是你又想把它當做一個包的一部分,你可以使用python -m package.subpackage.moduleX. -m參數(shù)告訴python把它當做一個模塊來加載,而不是頂層的腳本。

2:或許你并不想直接運行moduleX,你想在其它的腳本當中使用moduleX的函數(shù),比如說這個腳本是myfile.py。如果是這種情況,需要把myfile.py放在別的地方,而不是在package目錄里面。在myfile.py使用一下語句就可以正常工作了:from package.moduleA import spam.

注:對于上面說的這兩種情況,包目錄(比如上面的package)必須存在于python的搜索路徑下面(sys.path)。如果不存在,你將不能夠使用包中的任何東西。

自從python2.6,模塊的名稱不在決定使用__name__屬性,而是使用__packege__屬性。這就是為什么我避免使用__name__這么明確的名稱來代表一個模塊的名稱。自從python2.6,一個模塊的名稱是由__package__+'.'+__name__來確定的,如果__packege__是None的話,那么這個名稱就是__name__了。

到此這篇關(guān)于python相對包導(dǎo)入報“Attempted relative import in non-package”錯誤的文章就介紹到這了,更多相關(guān)python相對包導(dǎo)入報錯內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python使用pandas模塊實現(xiàn)表之間的關(guān)聯(lián)

    Python使用pandas模塊實現(xiàn)表之間的關(guān)聯(lián)

    在數(shù)據(jù)分析和處理中,表之間的關(guān)聯(lián)是非常常見的操作,本文為大家介紹了pandas中實現(xiàn)表之間的關(guān)聯(lián)有四種方式,感興趣的小伙伴可以了解一下
    2023-07-07
  • 一起來學習一下python的數(shù)據(jù)類型

    一起來學習一下python的數(shù)據(jù)類型

    這篇文章主要為大家詳細介紹了python的數(shù)據(jù)類型,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下希望能夠給你帶來幫助
    2022-01-01
  • 淺談在django中使用redirect重定向數(shù)據(jù)傳輸?shù)膯栴}

    淺談在django中使用redirect重定向數(shù)據(jù)傳輸?shù)膯栴}

    這篇文章主要介紹了淺談在django中使用redirect重定向數(shù)據(jù)傳輸?shù)膯栴},具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • python實現(xiàn)簡單貪吃蛇小游戲

    python實現(xiàn)簡單貪吃蛇小游戲

    這篇文章主要為大家詳細介紹了python實現(xiàn)簡單貪吃蛇小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • TensorFlow內(nèi)存管理bfc算法實例

    TensorFlow內(nèi)存管理bfc算法實例

    今天小編就為大家分享一篇TensorFlow內(nèi)存管理bfc算法實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Python的條件語句與運算符優(yōu)先級詳解

    Python的條件語句與運算符優(yōu)先級詳解

    這篇文章主要介紹了Python的條件語句與運算符優(yōu)先級,是Python入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-10-10
  • Python數(shù)據(jù)結(jié)構(gòu)之棧、隊列及二叉樹定義與用法淺析

    Python數(shù)據(jù)結(jié)構(gòu)之棧、隊列及二叉樹定義與用法淺析

    這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)之棧、隊列及二叉樹定義與用法,結(jié)合具體實例形式分析了Python數(shù)據(jù)結(jié)構(gòu)中棧、隊列及二叉樹的定義與使用相關(guān)操作技巧,需要的朋友可以參考下
    2018-12-12
  • 一文帶你深入了解Python中的二次移動平均法

    一文帶你深入了解Python中的二次移動平均法

    二次移動平均法,也稱為指數(shù)加權(quán)移動平均法,是一種用于平滑時間序列數(shù)據(jù)的算法。這篇文章主要通過示例來和大家聊聊二次移動平均法的使用,需要的可以了解一下
    2023-02-02
  • 異步任務(wù)隊列Celery在Django中的使用方法

    異步任務(wù)隊列Celery在Django中的使用方法

    對于網(wǎng)站來說,給用戶一個較好的體驗是很重要的事情,其中最重要的指標就是網(wǎng)站的瀏覽速度。因此服務(wù)端要從各個方面對網(wǎng)站性能進行優(yōu)化,這篇文章主要介紹了異步任務(wù)隊列Celery在Django中的使用方法,感興趣的小伙伴們可以參考一下
    2018-06-06
  • python使用openpyxl打開及讀取excel表格過程

    python使用openpyxl打開及讀取excel表格過程

    openpyxl是一個Python庫,用于讀寫Excel?2010?xlsx/xlsm文件,它允許你輕松工作與Excel表格,進行數(shù)據(jù)處理和分析,支持讀取、創(chuàng)建和修改Excel文件,甚至可以在Excel中插入圖表等,安裝非常簡單,只需要使用pip命令即可
    2024-09-09

最新評論