日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python中import 模块的路径问题

發布時間:2023/12/16 python 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python中import 模块的路径问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

對于系統的包我們導入沒有疑問

但是如果我們自己寫的文件夾里面的python文件呢?

自己寫的文件import時候會出現路徑問題的疑惑

比如同目錄下面的python文件被import 時候

和 其他目錄下面的python文件被import時候

根據當前的python文件是否為執行文件

import的python文件的路徑就是有區別的

1.先看看python如何定位到模塊文件的

使用 imoort a 或者 from a import func

使用這種import 的時候是如何定位到模塊 a的呢?

直接使用 import sys 的時候又是如何定位到sys這個模塊的呢?

這個學過python的都知道因為搜索路徑存在。默認先在當前目錄下搜索,

然后是python的安裝目錄下的文件

1.sys.path提供了搜索路徑

如果 import sys

使用 sys.path 是可以看到有一些目錄的

python按照這個目錄順序進行搜索。

2.文件的__name__提供了模塊名字

每一個Python對象有這個__name__屬性

如果當前的python為執行文件,此處簡稱為驅動文件,那么__name__的值就是__main__

可以理解為main函數

如果當前python不是執行文件,只是我們組織模塊用的,那么__name__就是該文件的相對路徑

3.python文件的定位就是 sys.path 和 __name__指定的路徑的拼接

2.看看自己寫的文件import的問題

下面做個試驗看看這個自己寫的文件import的問題

下面是做試驗用的文件目錄

folder1 目錄下 存放 a.py 和 b.py

folder2 目錄下 存放 c.py 和d.py?

每個文件里面簡單寫幾行代碼:

#a.py def f1():print("this is function f1 in a.py")print("a的__name__屬性是:"+__name__) #b.py def f2():print("this is function f2 in b.py")print("b的__name__屬性是:"+__name__) #c.py def f3():print("this is function f3 in c.py")print("c的__name__屬性是:"+__name__) #d.py def f4():print("this is function f4 in d.py")print("d的__name__屬性是:"+__name__)

試驗1:同目錄下的文件import --- a.py 為執行文件

在a.py 里面引入 文件b.py , 并且此時 a.py 為驅動文件,可以執行下a.py 看看結果

from b import f2#a.py def f1():print("this is function f1 in a.py")f2() print("a的__name__屬性是:"+__name__)

上面使用??

from b import f2

這種很好理解,可以定位到模塊 b

試驗2:同目錄下的文件import --- a.py 不執行

本次不執行 a.py , 我們弄一個demo.py 來作為驅動文件

然后在 demo.py 里面來 import a?

注意下,此時 demo.py 引入 a.py 時候使用的是?

from folder1.a

這里帶著路徑 folder1.a

# demo.py from folder1.a import f1, f2 import sysf1() f2() print(__name__)

然后運行下 demo.py:

居然報錯了

?有疑惑吧

剛才試驗1 里面直接執行 a.py 沒有錯誤啊

同樣的代碼,試驗2中在demo.py里面執行,就錯了,找不到模塊 b 了

為什么呢?

試驗3:在試驗2基礎上修改下a.py里面引入模塊b 的路徑

修改下? a.py

把 from b 修改為 from .b?

加了一個.?

from .b import f2#a.py def f1():print("this is function f1 in a.py")f2() print("a的__name__屬性是:"+__name__)

然后再運行下demo.py:

?疑問:

為什么此時需要修改下 a.py 里面 模塊b的imoport 路徑才可以運行通過??

簡單分析下:

對比下試驗1 和試驗2 其實還有區別的,

a.py 作為驅動文件和不作為驅動文件,還有驅動文件的目錄發生了變化

試驗1中:

a.py作為驅動文件,那么搜索路徑就是當前文件夾? ?import理解/folder1

也就是搜索路徑

那么b.py被引用,那么它的__name__就是 b? (相對路徑)

所以 2個組合起來是可以找到 b 的

試驗2中:

此時demo.py作為驅動文件,那么當前目錄?import理解/ 就是搜索路徑

此時demo.py要找到 模塊a , a被imort之后 ,那么a的__name__就是相對路徑 folder1.a

根據前面所說搜索路徑就是 sys.path 和當前模塊__name__路徑的拼接

所以demo.py加載 a 的時候實際上的搜索路徑是? ?import理解/folder1

加載a的時候,首先要去加載b

當前的搜索路徑是??import理解/folder1

此時b被引用,所以 b的__name__是? folder1.b

繼續拼接

可以看到 2個 如果直接組合在一起的話:?import理解/folder1/folder1/b

有 2個? folder1的 這個路徑是錯誤的

所以? 試驗2中? from b import f2? 此時就無法找到 模塊b 了

如何正確找到呢?

那么就需要修改下 import 的模塊路徑了

使用 from .b 之后 表示了加載當前目錄下面的模塊 b

當前目錄就是? /import理解/folder1? ,從而可以找到

如果 from 后面不加模塊路徑,那就是直接按照 上面的路徑拼接進行查找的

試驗4:import 不同目錄的文件--a.py作為驅動文件

先在 a.py 里面使用 folder2下面的 c

此時把 a.py作為驅動文件進行試驗,所以先把?from .b import f2 得改回來?

from b import f2 from folder2.c import f3 #a.py def f1():print("this is function f1 in a.py")f2() f3() print("a的__name__屬性是:"+__name__)

?此時會報錯誤,找不到模塊

根據前面結論 sys.path+模塊__name__指定路徑拼接

此時的搜索路徑為:

import理解/folder1

模塊c被引用,此時它的__name__是 folder2.c

那么拼接起來肯定無法在 folder1目錄下來找到 folder2的

此刻有人想不是相對路徑么,既然當前在 folder1下面,那么..就是上級目錄

所以使用? ?

from ..folder2.c import f3 試試

結果還是報錯的

?ValueError: attempted relative import beyond top-level package

說明 ..是行不通的? 不能使用..作為相對目錄去尋找

那該怎么辦呢??

只要能保證搜索路徑能找到這個模塊那就能import的

因此如果c.py的目錄也在這個搜索路徑里面就是可以的

試驗5:sys.path 來定位路徑

基于上面的試驗4代碼,當前問題是搜索路徑為??import理解/folder1

如何去尋找??import理解/folder2呢?

既然搜索路徑是通過這個 sys.path來進行的

那么修改這個 sys.path呢?

比如我們把上層目錄加入到 sys.path里面看看

sys.path.append("../") from b import f2 import sys sys.path.append("../") from folder2.c import f3 #a.py def f1():print("this is function f1 in a.py")f2() f3() print("a的__name__屬性是:"+__name__)

果然出來了

所以可以通過修改 sys.path 的值增加搜索路徑解決問題

此時使用sys.path 是可以使用 ..表示上層目錄的

通過上面的試驗可以看到搜索路徑的理解很重要

試驗6 :?import 不同目錄的文件--a.py 不執行

本次不借助sys.path的修改

此時的 a.py 如果不執行呢?

此時 先把 from b 要改回? from .b

下面這段代碼使用? demo.py來作為驅動文件執行

from .b import f2 from folder2.c import f3 #a.py def f1():print("this is function f1 in a.py")f2() f3() print("a的__name__屬性是:"+__name__)

此時再次驅動 demo.py執行

# demo.py from folder1.a import f1, f2 import sysf1() f2() print(__name__)

?可以看到 此時 a.py 中 使用??

from folder2.c import f3

這個是可以正常加載的

原因就是因為 當前搜索路徑變為了?import理解/

從而尋找模塊c 的時候 import理解/foleder2 是可以正常找到的

可見,這個搜索路徑多么重要

而且驅動文件所在的目錄也很重要

最好把它放到頂層根目錄下面

試驗7:如果使用 import b 不是 from b 這種呢

繼續使用demo.py作為驅動

然后我們在? a.py 里面 使用 import b的方式去加載 b

運行demo.py:

結果顯而易見,肯定找不到 b 的

此時必須使用

import folder1.b from .b import f2 from folder2.c import f3 import folder1.b #a.py def f1():print("this is function f1 in a.py")f2() f3() print("a的__name__屬性是:"+__name__)

很明細使用import b 這種方式

就是直接的把搜索路徑和當前的模塊名字路徑拼接起來的進行查找

總結

通過上面的試驗可以看到,能否找到我們自己寫的模塊文件

搜索路徑很重要的

而且還跟當前的 文件是否為 驅動文件有直接關系

如上面的 a.py

它作為驅動文件 時候 就可以直接 import b

但是如果是demo.py作為驅動文件的時候,a.py 里面必須是?

import folder1.b

都是因為當前搜索路徑搗的鬼

方法

1.可以使用 sys.path里面增加路徑的方式

? ?指定一些路徑加入到里面,這樣就可以搜索到我們自己寫的文件

2.將驅動文件放到最頂層,比如這里的 demo.py

? ?然后從最頂層的目錄為基準,里面寫的文件的路徑都是相對于它的

??

3.使用包

如果我們使用包,那么把包都部署在lib下面這樣lib本身在 sys.path 里面的

這樣像 系統包 那樣的使用方式使用,這樣不用擔心相對路徑的問題了

不管那種寫法,還是要明白搜索路徑是如何找到文件模塊的

總結

以上是生活随笔為你收集整理的python中import 模块的路径问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。