Intro to Modules and Packages

小型項目可以將所有代碼放到同一個 .py的文件中完成 但當項目變大時這種方式不利於代碼編寫及維護,而且對於團隊共同開發也不方便

使用module(模組 / 模塊) 及 package(套件 / 包)可以解決上述問題,這樣做的好處有: 1.模組是可重複使用的 2.每個模組中使用簡潔且更短的代碼 3.文件更有條理,可以將相同功能的代碼整理到同一模組中 4.代碼更容易維護

Module(模組 / 模塊) :每一個 .py 文件便是一個模組,模組名稱便是 .py 文件的文件名 Package(套件 / 包):一個資料夾中包含一個 init .py文件及其他 .py 文件組成,init .py文件內容可以是空白,但一定要有,有__init__ .py文件的資料夾才會辨識成套件 Library(庫) :相同功能的模組/套件組合而成的,主要有以下幾種: 1.標準庫:Python中自帶的,例如:os , sys , random , math , Tkinter… 2.第三方庫:由第三方機構經審核發行的庫,例如:numpy(科學計算),pandas(數據處理),scrapy(網頁爬蟲),PIL(圖像處理)….

當套件缺失 init .py文件時,Python3.2以後的版本是可以執行的,因為有透過PEP 420進行修正,採用namespace package(命名空間套件)這個方式進行處理所以沒有 init .py文件仍可以執行 Python Enhancement Proposals,簡稱PEP,中文是Python增强提案,向Python核心團隊提案,詳細介紹https://peps.python.org/pep-0001/ **無 init .py文件仍可執行相關文章:https://iter01.com/548257.html **namespace package(命名空間套件)相關文章: https://ithelp.ithome.com.tw/articles/10196775 https://python3-cookbook-personal.readthedocs.io/zh_CN/latest/c10/p05_separate_directories_import_by_namespace.html

python_102.jpg

當進行import時,會將引用的 .py 文件生成byte codes的 .pyc 文件並存放在__pycache__中,這可以加快下次執行的速度 當執行 .py 文件時,Python 會先看看有沒有這支 .py 文件的 .pyc 文件,如果有,而且 .py 文件的修改時間和 .pyc 文件一樣時,Python 就會讀 .pyc 文件,否則便會去讀原來的 .py 文件

Different Ways of Import

Python中的模塊導入語法:import… 及 from…import…

1.import ModuleName 這是好的導入方式,但可能因為ModuleName太長而使得代碼可讀性降低

2.import ModuleName as AnotherName 可以重新給模塊另一個名稱,最推薦的使用方式

3.from ModuleName import * 因為後續使用函數時不須加上***模塊名,***因此不容易發現個函數之間是否有關連,而且容易出現函數被重新賦值而使原本函數失去作用

4.from ModuleName import Function_1, Function_2, … 也是會出現函數被重新賦值而使原本函數失去作用

*函數被重新賦值問題可以通過 from … import … as … 語法來解決。

# import方式:import... 及 from...import...
# sample_module_1中有sample_func_A 及 sample_func_B / 
# sample_module_2中有sample_func_C 及 sample_func_D
# sample_module_3中有sample_func_E 及 sample_func_F / 
# sample_module_4中有sample_func_G , sample_func_H 及 sample_func_I
# 1.import ModuleName
import sample_module_1

sample_module_1.sample_func_A()
print('===' * 15)
# 2.import ModuleName as AnotherName
import sample_module_2 as mod

mod.sample_func_D()
print('===' * 15)
# 3.from ModuleName import *
from sample_module_3 import *

def sample_func_E():
    print('Hello! 來自main_code')

sample_func_E()
sample_func_F()
print('===' * 15)
# 4.from ModuleName import Function_1, Function_2, …
from sample_module_4 import sample_func_H, sample_func_I

def sample_func_H():
    print('Hello again!!  來自main_code')
sample_func_H()
sample_func_I()

--------------------------------------------
# 執行結果:
Hello! 來自sample_module_1
=============================================
Hello again!!  來自sample_module_2
=============================================
Hello! 來自main_code
Hello again!!  來自sample_module_3
=============================================
Hello again!!  來自main_code
Nice day  來自sample_module_4

python_103-1.jpg

如果有套件需要寫的話,導入語法將ModuleName 改成 PackageName.ModuleName 或PackageName.SubPackageName.ModuleName

1.import PackageName.ModuleName 2.import PackageName.ModuleName as AnotherName 3.from PackageName.ModuleName import * 4.from PackageName.ModuleName import Function_1, Function_2, …

# import方式:import... 及 from...import...
# myPackage中有sample_module_01(內有sample_func01_1 及 sample_func01_2)及中有sample_module_02(內有sample_func02)
# myPackage中有sub_package,sub_package中有sample_func_sub

import myPackage.sample_module_02

myPackage.sample_module_02.sample_func02()
print('===' * 15)

import myPackage.sub_package.sample_module_sub

myPackage.sub_package.sample_module_sub.sample_func_sub()
print('===' * 15)

import myPackage.sub_package.sample_module_sub as mod

mod.sample_func_sub()
print('===' * 15)

from myPackage.sample_module_01 import sample_func01_2

sample_func01_2()

--------------------------------------------
# 執行結果:
Hello! 來自myPackage中的module_02
=============================================
Hello! 來自sub_package中的module
=============================================
Hello! 來自sub_package中的module
=============================================
Hello again!! 來自myPackage中的module_01