Work

python-code-style

Python
Code Style
Package Management
Project Structure
Best Practices

Python 程式碼風格與專案架構指南

這篇文章將深入探討 Python 程式碼組織的核心概念,特別是 __init__.py 文件的重要性,以及如何設計可維護的大型專案架構。從基礎的包管理到現代專案設計模式,我們將一步步建立完整的開發知識體系。

什麼是 __init__.py

__init__.py 是 Python 的包初始化文件,告訴 Python 這個目錄是一個包 (package)。它的存在讓目錄可以被當作模組來匯入和使用。

Python 語法基礎說明

在開始之前,讓我們先了解 Python 與 Java 在語法上的主要差異:

# Python 語法特點 (與 Java 對比)
# 1. Python 沒有分號結尾,每行是一個語句
print("Hello World")  # 相當於 Java 的 System.out.println("Hello World");

# 2. Python 使用縮進表示代碼塊,而不是大括號
if True:
    print("這是 if 語句的內容")  # 相當於 Java 的 { }
    x = 1

# 3. Python 變數聲明不需要指定類型
name = "John"  # Java 需要: String name = "John";
age = 25       # Java 需要: int age = 25;

# 4. Python 函數定義使用 def 關鍵字
def greet(name):  # Java 需要: public void greet(String name) {
    return f"Hello, {name}"  # f-string 是 Python 3.6+ 的格式化語法

# 5. Python 沒有 public/private 等訪問修飾符,慣例使用下劃線
_private_var = "私有變數"  # 相當於 Java 的 private
public_var = "公開變數"   # 相當於 Java 的 public

基本功能

# __init__.py 示例
# 空的 __init__.py 文件已經足夠讓 Python 認識這個目錄是包
# 注意:Python 註釋使用 # 而不是 //

進階用法

# __init__.py 可以包含初始化代碼
# import 語法:from 模組 import 項目
from .main_module import MainClass  # 相當於 Java 的 import
from .utils import helper_function

# Python 變數不需要類型聲明
__version__ = "1.0.0"  # 相當於 Java 的 public static final String VERSION = "1.0.0";

# Python 列表相當於 Java 的 ArrayList
__all__ = ["MainClass", "helper_function"]  # 控制 import * 時匯出的項目

# Python 函數定義
def get_version():
    return __version__  # return 相當於 Java 的 return

Python 特殊方法 (__xx__) 簡介

__xx__ 是 Python 中的特殊方法(Special Methods),也被稱為魔術方法(Magic Methods)。這些方法讓你的類可以實現 Python 的內建操作。

為什麼需要特殊方法?

# 沒有特殊方法的類
class BasicClass:
    def __init__(self, value):
        self.value = value

# 使用時很麻煩
obj = BasicClass(42)
print(len([obj]))  # TypeError

# 有特殊方法的類
class SmartClass:
    def __init__(self, value):
        self.value = value

    def __len__(self):           # 實現 len() 函數
        return 1

    def __str__(self):           # 實現 str() 轉換
        return f"SmartClass({self.value})"

# 使用時很自然
obj = SmartClass(42)
print(len([obj]))  # 1
print(str(obj))    # SmartClass(42)

核心特殊方法

物件生命周期

class MyClass:
    def __init__(self, value):
        """構造函數,相當於 Java 的構造函數"""
        self.value = value

    def __new__(cls, *args, **kwargs):
        """創建實例,相當於 Java 的構造函數前處理"""
        instance = super().__new__(cls)
        return instance

    def __del__(self):
        """析構函數,相當於 Java 的 finalize()"""
        print("物件被銷毀")

字符串表示

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        """用戶友好的字符串,相當於 Java 的 toString()"""
        return f"{self.name} ({self.age}歲)"

    def __repr__(self):
        """開發者友好的字符串,用於調試"""
        return f"Person('{self.name}', {self.age})"

比較操作

class Number:
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):      # == 運算符
        """相當於 Java 的 equals()"""
        if isinstance(other, Number):
            return self.value == other.value
        return False

    def __lt__(self, other):      # < 運算符
        """相當於 Java 的 compareTo()"""
        if isinstance(other, Number):
            return self.value < other.value
        return NotImplemented

容器協議

class MyList:
    def __init__(self):
        self._items = []

    def __len__(self):           # len() 函數
        return len(self._items)

    def __getitem__(self, index): # [] 讀取
        return self._items[index]

    def __setitem__(self, index, value): # [] 賦值
        self._items[index] = value

    def __iter__(self):          # for 循環
        return iter(self._items)

常見的特殊方法總結

方法調用方式Java 對應
__init__obj = Class()構造函數
__str__str(obj)toString()
__eq__obj1 == obj2equals()
__lt__obj1 < obj2compareTo()
__len__len(obj)size()
__getitem__obj[key]get(key)
__call__obj()函數調用

包結構示例

my_package/
├── __init__.py          # 包初始化文件
├── module1.py          # 第一個模組
├── module2.py          # 第二個模組
└── subpackage/         # 子包
    ├── __init__.py
    └── submodule.py

Python 語法基礎與 Java 對比

基本語法差異

# Python 語法特點 (與 Java 對比)
# 1. Python 沒有分號結尾,每行是一個語句
print("Hello World")  # 相當於 Java 的 System.out.println("Hello World");

# 2. Python 使用縮進表示代碼塊,而不是大括號
if True:
    print("這是 if 語句的內容")  # 相當於 Java 的 { }
    x = 1

# 3. Python 變數聲明不需要指定類型
name = "John"  # Java 需要: String name = "John";
age = 25       # Java 需要: int age = 25;

# 4. Python 函數定義使用 def 關鍵字
def greet(name):  # Java 需要: public void greet(String name) {
    return f"Hello, {name}"  # f-string 是 Python 3.6+ 的格式化語法

# 5. Python 沒有 public/private 等訪問修飾符,慣例使用下劃線
_private_var = "私有變數"  # 相當於 Java 的 private
public_var = "公開變數"   # 相當於 Java 的 public

語法對比表

概念PythonJava說明
變數聲明name = "John"String name = "John";Python 不需要類型聲明
函數定義def func():public void func() {}Python 使用 def,Java 使用返回值類型
類定義class MyClass:public class MyClass {}Python 使用冒號和縮進
條件語句if x > 0:if (x > 0) {}Python 使用冒號,Java 使用括號和大括號
循環for item in list:for (String item : list) {}Python 的 for-in 相當於 Java 的 for-each
異常處理try: except:try { } catch { }Python 使用冒號,Java 使用大括號
註釋# 單行註釋// 單行註釋Python 單行註釋使用 #
多行註釋"""多行"""/* 多行 */Python 使用三引號
布林值True/Falsetrue/falsePython 首字母大寫
空值NonenullPython 使用 None
字符串"hello"'hello'"hello"Python 支持單雙引號
列表/陣列[1, 2, 3]int[] arr = {1, 2, 3};Python 使用方括號
字典/Map{"key": "value"}Map<String, String> mapPython 使用大括號
匯入from pkg import clsimport pkg.cls;Python 支持選擇性匯入
繼承class Child(Parent):class Child extends ParentPython 使用括號,Java 使用 extends

Python 專案架構設計

現代 Python 專案結構

良好的專案結構是維護性代碼的基礎:

# 推薦的專案結構
my_python_project/
├── __init__.py              # 根包初始化
├── main.py                  # 應用程序入口
├── setup.py                 # 包安裝配置
├── requirements.txt         # 依賴管理
├── src/                     # 源代碼目錄
│   ├── __init__.py
│   ├── core/               # 核心功能
│   │   ├── __init__.py
│   │   ├── pipeline.py     # 處理流程
│   │   └── config.py       # 配置管理
│   ├── services/           # 服務層
│   │   ├── __init__.py
│   │   ├── base_service.py
│   │   └── data_service.py
│   └── utils/              # 工具函數
│       ├── __init__.py
│       └── helpers.py
├── tests/                   # 測試代碼
│   ├── __init__.py
│   ├── test_pipeline.py
│   └── test_services.py
└── docs/                    # 文檔
    └── README.md

核心設計模式

1. 數據結構設計

# 數據結構的基本設計模式
class DataFrame:
    def __init__(self, data, metadata=None):
        self.data = data
        self.metadata = metadata or {}  # 如果 metadata 是 None,就使用空字典
        self.timestamp = datetime.now()

# 使用示例
frame = DataFrame("some data", {"type": "text"})
print(frame.data)  # 訪問屬性

2. 處理流程設計 (Pipeline Pattern)

class Pipeline:
    def __init__(self):
        self.stages = []

    def add_stage(self, stage):
        self.stages.append(stage)
        return self  # 返回 self 支持鏈式調用

    async def process(self, data):
        for stage in self.stages:
            data = await stage.process(data)
        return data

# 使用示例
pipeline = Pipeline()
result = await pipeline.add_stage(service1).add_stage(service2).process(data)

3. 服務層設計

class BaseService:
    def __init__(self, config=None):
        self.config = config or {}

    async def process(self, data):
        raise NotImplementedError("子類必須實現此方法")

class TextProcessingService(BaseService):
    async def process(self, data):
        return data.upper()  # Python 字符串方法

實際應用示例

以下是一個完整的 Python 專案結構示例:

# main.py - 應用程序入口
from src.core.pipeline import DataPipeline
from src.services import TextService, ImageService
from src.processors import FilterProcessor, TransformProcessor

async def main():
    # 初始化服務
    text_service = TextService(config={"language": "zh-tw"})
    image_service = ImageService(config={"quality": "high"})

    # 創建處理器
    filter_proc = FilterProcessor(criteria={"type": "valid"})
    transform_proc = TransformProcessor(rules={"normalize": True})

    # 構建處理管道
    pipeline = (
        DataPipeline()
        .add_stage(text_service)
        .add_stage(filter_proc)
        .add_stage(transform_proc)
        .add_stage(image_service)
    )

    # 處理數據
    input_data = {"text": "sample data", "images": ["img1.jpg"]}
    result = await pipeline.process(input_data)

    return result

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

Python 程式碼風格關鍵原則

init.py: 包管理的基礎

  • 包識別: Python 通過 __init__.py 識別目錄為包
  • 初始化: 可包含包級別的初始化代碼
  • 匯入控制: 通過 __all__ 控制 from package import * 的行為
  • 版本管理: 常存放包的版本信息和元數據

設計模式應用

  1. 數據結構設計: 使用類和字典設計靈活的數據結構
  2. 處理流程設計: 實現 Pipeline 模式處理數據流
  3. 服務層設計: 遵循單一責任原則設計服務組件
  4. 錯誤處理: 使用異常處理確保程序健壯性

代碼風格建議

  1. 命名規範: 使用有意義的變數和函數名稱
  2. 模組化: 將相關功能組織在單一模組中
  3. 文檔化: 為公共 API 撰寫詳細的文檔字符串
  4. 類型提示: 在適當的地方使用類型提示
  5. 測試覆蓋: 為關鍵功能編寫單元測試

總結

掌握 Python 的程式碼風格和專案架構設計是成為優秀開發者的關鍵。從基礎的 __init__.py 概念到現代專案設計模式,這些原則為開發可維護、高質量的 Python 應用提供了堅實的基礎。

通過遵循這些最佳實踐,你將能夠建立清晰且易於維護的代碼結構,開發出更加健壯和高效的 Python 應用。

TY的智慧庫

你有事?
問前想清楚,機會不是誰都有。

💡 建議主題:

放大圖片