python-模塊的分類與導入
1,什么是模塊:
在計算機程序的開放過程中,隨着程序代碼越寫越多,在一個文件里代碼就會越來越長,越來越不容易維護。
為了編寫可維護的代碼,我們把很多函數分組,分別放到不同的文件里,這樣,每個文件包含的代碼就相對較少了,很多編程語言都采用這種組織代碼的方式。
在Python中,一個.py文件就稱之為一個模塊(Module)。
2,使用模塊的好處:
- 提高可維護性
- 可重用
- 避免函數名和變量名沖突
3,模塊的分類
- 內置標准模塊(又稱標准庫)執行help(‘Modules’)查看所有Python所有自帶模塊列表。
- 第三方開開源塊,可通過pip install 模塊名 聯網安裝, djiango
- 自定義模塊
4,模塊調用
1 import module 2 3 from module import xx 4 5 from module .xx.xx import xx as rename 6 7 from module .xx.xx import * #不推薦
注意:模塊一旦被調用,即相當於執行了另外一個py文件里的代碼
1,import random 導入模塊的所有方法
這會將對象(這里的對象指的是包、模塊、類或者函數,下同)中的所有內容導入。如果該對象是個模塊,那么調用對象內的類、函數或變量時,需要以module.xxx
的方式。
2,import multiprocessing as mul 模塊別名
3,from django.core import handlers 導入模塊的單個方法
從某個對象內導入某個指定的部分到當前命名空間中,不會將整個對象導入。這種方式可以節省寫長串導入路徑的代碼,但要小心名字沖突。
4,from socket import * 導入模塊的所有方法 不推薦
將對象內的所有內容全部導入。非常容易發生命名沖突,請慎用!
5,自定義模塊
這個最簡單, 創建一個.py文件,就可以稱之為模塊,就可以在另外一個程序里導入
6,模塊查找順序
python解釋器會按照列表順序去依次到每個目錄下去匹配你要導入的模塊名,只要在一個目錄下匹配到了該模塊名,就立刻導入,不再繼續往后找。
注意列表第一個元素為空,即代表當前目錄,所以你自己定義的模塊在當前目錄會被優先導入。
默認情況下,模塊的搜索順序是這樣的:
- 當前執行腳本所在目錄
- Python的安裝目錄
- Python安裝目錄里的site-packages目錄
其實就是“自定義”——>“內置”——>“第三方”模塊的查找順序。任何一步查找到了,就會忽略后面的路徑,所以模塊的放置位置是有區別的。
7,開源模塊學習的安裝方式
http://pypi.python.org/pypi 是python的開源模塊庫,是python的開源模塊庫,截止2018年8月 ,已經收錄了147,422個來自全世界python開發者貢獻的模塊,幾乎涵蓋了你想用python做的任何事情。
1.直接在上面這個頁面上點download,下載后,解壓並進入目錄,執行以下命令完成安裝
1 編譯源碼 python setup.py build 2 安裝源碼 python setup.py install
2.直接通過pip安裝
1 pip3 install paramiko # parmiko 是模塊名
pip命令會自動下載模塊包並完成安裝。
軟件一般會被自動安裝你python安裝目錄的這個子目錄里
1 /your_python_install_path/3.6/lib/python3.6/site-packages
p ip命令默認會連接在國外的python官方服務器下載,速度比較慢,你還可以使用國內的豆瓣源,數據會定期同步國外官網,速度快好多
sudo pip install -i http://pypi.douban.com/simple/ alex_sayhi --trusted-host pypi.douban.com #alex_sayhi是模塊名
使用
下載后,直接導入使用就可以,跟自帶的模塊調用方法無差,演示一個連接linux執行命令的模塊
1 #coding:utf-8 2 3 import paramiko 4 5 ssh = paramiko.SSHClient() 6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 7 ssh.connect('192.168.1.108', 22, 'alex', '123') 8 9 stdin, stdout, stderr = ssh.exec_command('df') 10 print(stdout.read()) 11 ssh.close(); 12 13 執行命令 - 通過用戶名和密碼連接服務器
8,包(Package)
當你的模塊文件越來越多,就需要對模塊文件進行划分,比如把負責跟數據庫交互的都放一個文件夾,把與頁面交互相關的放一個文件夾,
為了避免模塊名沖突,Python又引入了按目錄來組織模塊的方法,稱為包(Package),包是模塊的集合,比模塊又高一級的封裝。通俗來說,在里面一個文件夾可以管理多個模塊文件,這個文件夾就被稱為包
沒有比包更高級別的封裝,但是包可以嵌套包,就像文件目錄一樣:如下圖
最頂層的Django包封裝了contrib子包,contrib包又封裝了auth等子包,auth又有自己的子包和一系列模塊。通過包的層層嵌套,我們能夠划分出一個又一個的命名空間。
包名通常為全部小寫,避免使用下划線。
1 __int__.py用於標識當前文件夾是一個包。 2 3 python2,包就是文件夾,但該文件夾下必須存在 __init__.py 文件, 該文件的內容可以為空。__int__.py用於標識當前文件夾是一個包。 4 5 在python3里,即使目錄下沒__int__.py文件也能創建成功,猜應該是解釋器優化所致,但創建包還是要記得加上這個文件吧。
9,跨模塊導入
os.path.abspath(__file__) # 返回絕對路徑 print(__file__) # 打印改文件的相對路徑 os.path.dirname(__file__) # 打印該文件父目錄 相對路徑
1 如何實現在crm/views.py里導入proj/settings.py模塊?
import
sys, os
print
(
dir
())
print
(__file__)
# 打印改文件的相對路徑
BASE_DIR3
=
os.path.abspath(__file__)
# 返回絕對路徑
print
(BASE_DIR3)
BASE_DIR1
=
os.path.dirname(__file__)
# 打印該文件父目錄 相對路徑
BASE_DIR2
=
os.path.dirname(os.path.dirname(__file__))
# 打印該文件父目錄,父目錄 相對路徑
print
(BASE_DIR1)
print
(BASE_DIR2)
# 兩個模塊的父目錄加入到path路徑中,
# 然后就可以跨模塊導入了
BASE_DIR
=
os.path.dirname((os.path.dirname((os.path.abspath(__file__)))))
print
(BASE_DIR)
sys.path.append(BASE_DIR)
# 'C:\\PycharmProjects\\Luffy_project\\21天入門\\crm']
print
(sys.path)
from
proj
import
settings
settings.say_hi()
0,相對導入,絕對導入
文件夾被python解釋器視作package需要滿足兩個條件:
1.文件夾中必須有__init__.py文件,該文件可以為空,但必須存在該文件。
2.不能作為頂層模塊來執行該文件夾中的py文件(即不能作為主函數的入口)。
注:雖然python支持相對導入,但對模塊間的路徑關系要求比較嚴格,處理不當就容易出錯,so並不建議在項目里經常使用。
所以這個問題的解決辦法就是,既然你在views.py里執行了相對導入,那就不要把views.py當作入口程序,可以通過上一級的manage.py調用views.py
11,_all_變量
如果包定義文件__init__.py
中存在一個叫做__all__
的列表變量,那么在使用from package import *
的時候就把這個列表中的所有名字作為要導入的模塊名。
例如在example/p1/__init__.py
中包含如下代碼:
1 __all__ = ["x"]
- 這表示當你使用
from example.p1 import *
這種用法時,你只會導入包里面的x子模塊。 - import sendmsg #通過這個方式不受影響
1 # say_hi文件 2 3 __all__ = ["test1","num"] # 只能讓調用test1,num1 4 5 def test1(): 6 print("----test1") 7 8 def test2(): 9 print("----test2") 10 11 num = 1
1 # import調用模塊 2 import say_hi 3 say_hi.test1() 4 say_hi.test2()
----test1
----test2
1 # from 調用模塊 2 from say_hi import * 3 test1() 4 test2() 5 6 7 # error 8 ----test1 9 Traceback (most recent call last): 10 File "C:/PycharmProjects/Luffy_project/21天入門/3模塊/1test.py", line 3, in <module> 11 test2() 12 NameError: name 'test2' is not defined