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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

关于python导入模块和package的一些深度思考

發布時間:2023/11/28 生活经验 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于python导入模块和package的一些深度思考 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

在python中有導入模塊和導入package一說,這篇文章主要介紹導入模塊和package的一些思考。
首先什么是模塊?什么是package?
模塊:用來從邏輯上組織python代碼(變量,函數,類),本質上就是以.py結尾的python文件
package:本質上就是一個目錄,但是必須帶一個init.py的文件,它是用來從邏輯上組織模塊的
import的本質是什么?
導入模塊的本質:就是把python文件拿來解釋一遍
導入包的本質:就是執行該package下的init.py文件、

深入思考

導入模塊

如果我現在有一個這樣的目錄:

在bin文件目錄下的hello.py內容是:

def hello():print('i am in bin dir')

在Day5文件目錄下的hello.py內容是:

def hello():print('i am in Day5 dir')

在pythonFile文件目錄下的hello.py內容是:

def hello():print('i am in pythonFile dir')

如果我現在在bin目錄下的test.py下寫入

import hello
hello.hello()

會出現的結果是什么呢?
大家很自然會想到是

i am in bin dir

是的確實是這樣的。但是為什么呢?
這個需要提及到環境變量的問題,我們可以看看當前文件所處的環境變量到底里面有什么?
使用下面的語句:

import sys, os
print('--------')
for path in sys.path:print(path)
print('--------')

其中sys.path是所有環境變量的所構成的列表,我們將里面的內容分行打印。可以得到:

--------
D:\0 sty file\myCode\pythonFile\Day5\bin
D:\0 sty file\myCode\pythonFile
C:\ProgramData\Anaconda3\python36.zip
C:\ProgramData\Anaconda3\DLLs
C:\ProgramData\Anaconda3\lib
C:\ProgramData\Anaconda3
C:\ProgramData\Anaconda3\lib\site-packages
C:\ProgramData\Anaconda3\lib\site-packages\Babel-2.5.0-py3.6.egg
C:\ProgramData\Anaconda3\lib\site-packages\win32
C:\ProgramData\Anaconda3\lib\site-packages\win32\lib
C:\ProgramData\Anaconda3\lib\site-packages\Pythonwin
--------

這是我電腦里面的當前文件運行時候的環境變量。我們可以知道導入模塊和package時候,我們的程序會從這個sys.path中從前到后尋找這些目錄下有沒有我們要找的模塊,可以看見D:\0 sty file\myCode\pythonFile\Day5\bin是在第一個的所有我們直接導入hello模塊。python找到的D:\0 sty file\myCode\pythonFile\Day5\bin里面的hello.py找到之后,就不找了,然后打印出來了。

導入的問題來了

現在問題來了,我現在就想要導入D:\0 sty file\myCode\pythonFile\Day5下面的hello,那我應該怎么辦?
我們知道在python中我們可以找到當前文件所在目錄的父目錄,然后將他加入到運行環境時候的環境變量中去,注意是運行環境中的,因為在當前python文件運行結束后,這個環境變量就釋放了。
我們可以了解如下語句:

import sys, os    # 導入系統模塊
print(os.path.abspath(__file__))  #打印當前文件所處的絕對路徑
print(os.path.dirname(os.path.abspath(__file__))) #打印當前文件所處的目錄
# 打印當前文件所處的目錄的父目錄
print( os.path.dirname(os.path.dirname(os.path.abspath(__file__))))# Outputs:
# D:\0 sty file\myCode\pythonFile\Day5\bin\test.py
# D:\0 sty file\myCode\pythonFile\Day5\bin
# D:\0 sty file\myCode\pythonFile\Day5 

然后我們就可以在寫下如下的代碼:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)  # 將BASE_DIR加入到系統環境變量

我們將當前文件所在目錄的父目錄加入到環境變量中去,然后我們在打印下sys.path得到:

--------
D:\0 sty file\myCode\pythonFile\Day5\bin
D:\0 sty file\myCode\pythonFile
C:\ProgramData\Anaconda3\python36.zip
C:\ProgramData\Anaconda3\DLLs
C:\ProgramData\Anaconda3\lib
C:\ProgramData\Anaconda3
C:\ProgramData\Anaconda3\lib\site-packages
C:\ProgramData\Anaconda3\lib\site-packages\Babel-2.5.0-py3.6.egg
C:\ProgramData\Anaconda3\lib\site-packages\win32
C:\ProgramData\Anaconda3\lib\site-packages\win32\lib
C:\ProgramData\Anaconda3\lib\site-packages\Pythonwin
D:\0 sty file\myCode\pythonFile\Day5
--------

我們可以看出D:\0 sty file\myCode\pythonFile\Day5加到了sys.path的最后一個,現在我們將之前的開頭的寫的

import hello
hello.hello()

一定要注釋,一定要注釋,一定要注釋,因為如果不去掉的話,這個hello.hello()方法就已經存放在內存里面了,不管你后面如何去該環境變量,python會始終去找到內存中直接有的hello()方法。
我們將這行代碼加到test.py的最后面,運行得到結果是:

i am in bin dir

這是為什么呢,原因還是那個sys.path中個路徑順序的問題,如果我們要讓我們設置的BASE_DIR 中的模塊首先導入我們就需要用列表中的insert()方法2而不是‘append()’的了,這就避免了再環境變量中已經有的路徑有同名的模塊。
我們改為:

sys.path.insert(0, BASE_DIR)

發現輸出的結果就是

i am in Day5 dir

完整代碼如下:

# import hello   #使用添加環境變量后的模塊一定要注釋到
# hello.hello()import sys, os
print('--------')
for path in sys.path:print(path)
print('--------')BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#sys.path.append(BASE_DIR)
sys.path.insert(0, BASE_DIR)print('--------')
for path in sys.path:print(path)
print('--------')import hello
hello.hello()

最后提一下:
如果我們要使用pythonFile下的hello中hello(),道理還是一樣的,大家自己去實現吧。

導入package

導入package時候設置環境變量的問題和導入模塊是一樣的,就不贅述了,但是需要注意的一點是導入package后,package下的init.py里的內容是自動執行的。
如我在test_package下的init.py中寫入

print('i am in test_package __init__')

當我們在

import test_package

后就自動執行了,這在我們管理很多文件時候,進行初始化的作用相當好用啊。

轉載請注明出處:
CSDN:樓上小宇_home:http://blog.csdn.net/sty945
簡書:樓上小宇:http://www.jianshu.com/u/1621b29625df

總結

以上是生活随笔為你收集整理的关于python导入模块和package的一些深度思考的全部內容,希望文章能夠幫你解決所遇到的問題。

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