【Python】 Module 與 Package 不應該拿來比較

【Python】 Module 與 Package 不應該拿來比較

網路上充斥著很多 **Module and Package** 的說明文章,會讓初學者誤以為這兩個是同層級的東西,但其實不是。

網路上充斥著很多 Module and Package 的說明文章,會讓初學者誤以為這兩個是同層級的東西,但其實不是。

什麼是 Module

一個 py 檔,宣告的 Variable、Function、Class,可以被其他檔案引用。

post.py

class Post:
    # 建構式
    def __init__(self):
        self.titles = []

    # 新增文章
    def add_post(self, title):
        self.titles.append(title)

    # 刪除文章
    def delete_post(self, title):
        self.titles.remove(title)

about.py

readme = "this is about.py"

#取得作者
def get_author():
    return "Logan"

#取得電子郵件
def get_email():
    return "[email protected]"

main.py

# Module
from post import Post
from about import (get_author, get_email)

new_post = Post()
new_post.add_post("Hello World")

print(new_post.titles) # ['Hello World']
print(get_author()) # Logan
print(get_email()) # [email protected]

也可以用 from ... import * 引用模組內的所有物件,但這這樣的寫法,可能會發生命名衝突而被覆寫(overwrite)的風險。

main.py

# Module
from about import *

print(readme) # this is about.py
print(get_author()) # Logan
print(get_email()) # [email protected]

Package 用法

當 Module 越來越多,需要將相似的 Module 組織為 Package,而 Package 就是一個容器(資料夾),包含一個或多個 Module,並且擁有 __init__.py 的檔案。

嘗試將剛剛的兩個檔案打包成一個 Package,結構如下。

/
├─ main.py
└─ blog/
   ├── __init__.py
   ├── about.py
   └── post.py
# Package
from blog import post
from blog import about

new_post = post.Post()
new_post.add_post("Hello World")

print(new_post.titles) # ['Hello World']
print(about.readme) # this is about.py
print(about.get_author()) # Logan
print(about.get_email()) # [email protected]

Package 觀念

官方文件 來看,Package 是 Module 的一種用法。

Package 是 Module 組織化的一種用法。

透過 type 印出 Module 會是一個 module 的資料型態(data type)

import random
type(random)
# <class 'module'>

但是如果透過 type 印出 Package,他還是一個 Module

import blog
type(blog)
# <class 'module'>

Dir function

Python 提供了一個 dir function,用來顯示物件的屬性(Attribute)與方法(Method)

from blog import about
dir(about)
# ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'get_author', 'get_email', 'readme']

Import 的各種寫法

Module

import [module]

import 整個 random,可以使用 random 底下的 function

import random
print(random.randint(0, 5))

from [module] import [name1, name2]

從 random 裡 import 其中的 function

from random import randint
print(randint(0, 5))

import [module] as [new_name]

把 random 重新命名為 rd

import random as rd
print(rd.randint(0, 5))

from [module] import *

不推薦用法,import random 底下的東西,會有 Overwrite 風險

from random import *
print(randint(0, 5))

Logan

資深軟體工程師,熱衷寫程式與智慧家庭 🏠

本文採用 CC BY-NC 4.0 授權

相關文章