從全流程的角度來了解python包的使用,你也許會有不一樣的認識

在python中,只要我們一談到包或模組,基本預設說的就是包的匯入和使用。也就是說只要我們知道包的名字,匯入後知道怎麼使用基本就可以了,但本人認為,我們僅僅瞭解的是包的一部分,若想對包有個整體的認識,我們還需知道包的整個製作和使用流程。

從全流程的角度來了解python包的使用,你也許會有不一樣的認識

在這個圓環流程圖中,其實並沒有嚴格的前後順序,你也可以先進行包的開發、製作、上傳、下載、安裝,最後再到包的匯入和使用,同樣也可以直接匯入現成包直接使用 。那麼接下來我們就從最基本的包開始介紹 。

1。模組和包(包的匯入和使用)

談到包,你就不得不知道模組 ,因為很多包就是由模組構成的 。所以,接下來我們就來了解下python中的模組 。

1.1 模組

1.什麼是模組

所謂的模組,其實就是一個python ,以。py結尾的檔案 ,檔案內包含了類、函式、方法等 。

myproject├─ __init__。py├─ abc。py└─ bcd。py

其中,abc和bcd就是python的模組 ,後續模組的匯入和使用也是直接這兩個名字即可 。

在python中,有很多現成的模組是可以直接使用的,比如os模組 。若使用其功能時只需要完成兩步即可,分別是:

模組的匯入

模組內函式、函式、類的呼叫

2.模組的分類

python中的模組,我們可以將其分為三類,分別是:

系統自帶模組 ,相當於安裝python包就將這些模組自動安裝上了,這一型別的模組在python的整個環境中全域性有效,任何地方都可匯入直接使用 。其中典型的模組以os為主 。

第三方模組/包 ,使用時需要先下載安裝並配置環境變數,在配置的環境變數內模組可以被匯入使用 。這一型別的包或模組是我們最常用的,因為大多數情況下,系統模組都不能滿足我們的需求 ,需要藉助於大量的第三方模組/包才能完成工作 。

自定義模組 ,專案內部開發的模組 ,可以在專案內部使用 ,超出專案內即無法使用 。

3.模組匯入

在上面我們已經介紹到,若想要使用現成的模組,第一個步驟就是匯入,在python中匯入有兩種方法,分別是:

# 第一種匯入方式:import 模組名# 需求1:匯入os模組 import os# 需求2 :匯入自己編寫的模組,abc 注意 : 匯入自己編寫的模組時需要注意路徑 。import abc # 說明: 透過這種方式匯入的模組,使用時也需要加入模組的名字 ,比如os模組內有個getcwd()方法,在使用這個方法時,也必須是os。getcwd()才行 。

使用上面的匯入方式有一定的弊端,比如說os內部有很多方法,但我只是使用其中的幾個方法,但是透過

import os

匯入後將os內所有方法和類全部匯入,佔用系統資源較大 ;其次就是每次使用具體方法或類時,必須前面加模組名 ,呼叫起來不太便捷 。以上的這些問題該如何解決呢 ?答案就是使用第二種匯入方式 :

from 模組 import 方法|類

# 第二種匯入方式from 模組名 import 成員名 # 匯入 os裡的getcwd方法from os import getcwd# 說明 :透過這種方式匯入後 ,使用getcwd()方法時直接呼叫getcwd即可。

從全流程的角度來了解python包的使用,你也許會有不一樣的認識

4.模組路徑搜尋

無論是後面介紹的包,還是這裡要介紹的模組,直接進行了匯入操作 ,它就會先去找到這個模組/包 ,如果在指定的路徑下搜尋該模組,如果找到,則匯入成功 ,否則匯入失敗 。具體搜尋的先後順序依次為:

程式的當前路徑

python的環境變數路徑

python標準連結庫路徑

以上的路徑組合起來就是sys。path所包含的路徑 ,而python會選擇在搜尋路徑中的第一個符合匯入檔名的檔案作為匯入模組,找到後即停止後面的搜尋 。所以若你自定義的模組和其它路徑下的模組重名,你又想要用到自定義模組,就可以把自定義模組放在前面 。

同時還需要注意的是,自定義模組不能和系統模組重名,否則會報錯 。

從全流程的角度來了解python包的使用,你也許會有不一樣的認識

1.2 包

1.什麼是包

包是一個包含多個模組的特殊目錄,目錄裡有檔案和目錄的組合 ,其目錄下有一個特殊檔案__init__。py,這也是包和目錄的最主要區別 。

myproject├─ __init__。py├─ mypack01 ├─ __init__。py├─ mydir├─ ab。py└─ bc。py# 說明:① 。 其中myproject就是最外層的包 ,其中每個包下都會有個__init__。py的檔案,這也是區別普通目錄和包的最主要區別 。其中__init__。py中可以是空也可以有python程式碼 。② 。 mypack01是子包 ,mydir是目錄③ 。 ab。py和bc。py是包下的模組

其中包和模組的使用方式一樣,同樣需要先匯入後呼叫(使用 ),這裡就不再贅述。

從全流程的角度來了解python包的使用,你也許會有不一樣的認識

2。__init__介紹

這裡需要介紹下__init__這個特殊的檔案,我們都知道它這個裡面可以寫程式碼,也可以不寫 ?但是很多情況下我們並不知道,這個檔案中到底該寫什麼程式碼 ?這個檔案到底有什麼作用呢 ?我們通過幾段程式碼來展示它的作用 。

先看下兩個模組(ab。py和bc。py)內的程式碼,

# 檔案:ab。py def div(a,b): return a // b def mul(a,b): return a * b

# 檔案 : bc。py def add(a,b): return a + b def min(a,b): return a - b

如果我想在test。py中呼叫以上兩個檔案中的函式,可以是如下的寫法 :

import mypack01。ab import mypack01。bc print(mypack01。ab。mul(3,4)) #輸出:12 print(mypack01。bc。add(3,4)) #輸出 :7

透過以上的匯入方法可以看到,能得到正確的結果 。接下來我們做個試驗 ,匯入時只寫父包名 ,不寫子包名 。具體如下圖 :

從全流程的角度來了解python包的使用,你也許會有不一樣的認識

只匯入父包名就會報錯 ,當滑鼠移動到ab或bc上時, 提示了一句

Cannot find reference ‘bc’ in __init__。py

, 大體意思是在__init__。py中找不到bc 。 於是我們在__init__。py中把這個模組匯入 ,具體程式碼如下:

# mypack01包下的__init__。py import mypack01。bcimport mypack01。ab

從全流程的角度來了解python包的使用,你也許會有不一樣的認識

以上的兩個截圖可以看到,test。py檔案中的程式碼沒變,而所變化的就是__init__。py 。 那麼這時__init__。py 到底起到了什麼作用呢 ?結合著上面的提示 ,我們可以總結出:

在其它模組import後跟包名,其實匯入的是init.py檔案

,也就是說只要你的程式碼匯入其它包時,就會自動執行匯入包下的__init__。py程式碼 。

那麼,以上的結論在實際場景中到底有什麼作用呢 ? 透過以上的程式碼肯定是看不出來的 ,我們可以想象一種場景, 假設我們有很多模組都要呼叫mypack01中的幾個函式 ,是不是要在每個模組都要寫幾個匯入語句啊 ,這個時候我們就可以將匯入語句寫到__init__。py程式碼中,這樣是不是就節省了一部分程式碼呢 ? 這種場景不正是很多模組呼叫公共類庫時會遇到的情形嗎 ,所以 ,就可以使用__init__。py進行初始化一些匯入 。

還有另外一種情況,可以用於

from package import *

, 這個*代表要把package包內的所有模組統統匯入 。但有時候我們不希望部分模組被匯入 ,因為部分模組只是被內部使用的,若被其它模組匯入後,那就變為公共資源了 。這個時候怎麼控制呢 ?答案就是在__init__。py中加入一個__all__變數列表 。

從全流程的角度來了解python包的使用,你也許會有不一樣的認識

2。包的製作與上傳

有時候我們開發的包也想供外界使用,你就可以把你的原始包製作成可供pip或者easy_install安裝的包 。具體制作步驟如下:

在包對應的專案下建立必要的檔案 ,分別為setup。py,LICENSE,README。md 。

從全流程的角度來了解python包的使用,你也許會有不一樣的認識

2。編寫readme。md檔案和setup。py指令碼 。編寫自己的README。md檔案

### 1。包功能介紹### 2。安裝方法### 3。引數說明### 4。聯絡方式編寫自己的setup。py

編寫自己的setup。py

import osimport setuptools# 讀取readme檔案with open(“README。md”, “r”,encoding=‘utf-8’) as f: readme = f。read()setuptools。setup( name=“mypack”, #包名稱 version=“0。0。1”, #版本 author=“Example Author”, #包郵箱 author_email=“author@example。com”, #作者郵箱 description=“A small example package”, #包描述 long_description=readme, #長描述,通常是readme ,打包到PiPy需要 。 url=“https://github。com/pypa/sampleproject”, #專案URL packages=setuptools。find_packages(), #專案中需要的包 classifiers=[ #程式的所屬分類列表 ‘Operating System :: Microsoft’, ‘Operating System :: POSIX’, ‘Operating System :: Unix’, ‘Topic :: NLP’, ‘Topic :: Software Development :: Libraries :: Python Modules’, ‘Programming Language :: Python :: 3。5’, ‘Programming Language :: Python :: 3。6’, ‘Programming Language :: Python :: 3。7’, ‘Programming Language :: Python :: 3。8’, ],)

3。進行打包 ,其中最常見的兩種打包方式

# 以下的兩個命令生成不同的格式 ,python setup。py bdist_egg # 生成類似 mypack-0。0。1-py3。6。egg,支援 easy_install安裝python setup。py sdist # 生成類似 mypack-0。0。1。tar。gz,支援 pip 安裝

從全流程的角度來了解python包的使用,你也許會有不一樣的認識

以上截圖分別是透過以上兩個命令生成的的安裝包 ,如果是本地用的話,就可以直接透過pip 或者easy_install安裝 。但如果你想開源,你需要上傳到PyPi

4。上傳PyPi

在https://pypi.python.org/pypi

上註冊一個賬號

在本地的使用者目錄下新建檔案:

.pypirc

,比如我的路徑為:C:\Users\zhjy。pypirc 檔案內容為:

[distutils] index-servers=pypi [pypi]repository = https://upload。pypi。org/legacy/username = yournamepassword = youpassword

3。安裝twine,

pip install twine

4。使用twine進行上傳 ,

twine upload dist/*

。這樣你的包就可以被全世界下載了 。

3。包的下載與安裝

包的下載和安裝主要用到pip ,這裡就主要介紹下pip的使用 ,pip雖然使用它非常簡單,但是它的引數非常多,很多情況下我們都會使用到 。

以安裝pymysql為例

命令

說明

舉例

pip ——version

檢視pip版本

pip install packagename

安裝包

pip install pymysql

pip install packagename=0。9。3

安裝指定版本

pip install pymysql=0。9。3

pip install packagename>=0。8。1

安裝最低版本

pip install pymysql>=0。8。1

pip install ——upgrade packagename

升級指定包

pip install ——upgrade pymysql

pip uninstall packagename

解除安裝指定包

pip uninstall pymysql

pip search packagename

搜尋指定包

pip search pymysql

pip show packagename

檢視安裝包的資訊

pip show pymysql

pip list

列出以安裝的包

pip list -o

列出可升級的包

pip freeze

列出以安裝的包,包名==版本顯示

pip freeze > 檔案

匯出到檔案

pip freeze > a。txt

pip install -r requirements。txt

從檔案中安裝包

pip install packagename -i 映象URL

指定映象下載

pip install pymysql -i https://pypi。tuna。tsinghua。edu。cn/simple/

pip ——default-timeout=600 install packagename

設定超時時間

pip install pymysql ——default-timeout=600