理解 Python 中的 __str__ 與 __repr__ 方法

更新日期: 2024 年 11 月 18 日

在 Python 中,物件本身的字串表示通常用於調試、日誌記錄或向使用者展示物件資訊。

為了讓物件的輸出更加可讀和有意義,Python 提供了兩個魔術方法:__str____repr__

這兩者有著不同的用途,但初學者往往容易混淆它們的差異與應用場景。

本文將通過範例詳細講解這兩個方法的作用與原理,幫助你更好地理解和使用它們。


前言

當我們打印一個物件時,若該物件未定義特定的顯示方法,Python 會輸出該物件的記憶體位置資訊。例如:

class Cat:
    pass

kitty = Cat()
print(kitty)

輸出類似以下結果:

<__main__.Cat object at 0x7f8b7c3f5ac0>

這樣的輸出對開發者或使用者來說幾乎沒有任何資訊。

因此,我們可以通過覆寫 __str____repr__ 方法,來讓物件的輸出更有意義。


基本使用範例

以下是添加 __str____repr__ 方法的例子:

class Cat:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return f"str = {self.name}"

    def __repr__(self):
        return f"repr = {self.name}"

kitty = Cat('安安')
print(kitty)

輸出:

str = 安安

方法解析

  1. __str__
    • 用於定義物件的「可讀字串表示」,通常是給使用者看的。
    • 當使用 print() 函數或 str(obj) 時,會調用此方法。
  1. __repr__
    • 用於定義物件的「正式字串表示」,通常是給開發者看的,應該提供物件的詳細資訊。
    • 當在交互式解釋器中直接輸入物件名稱時,或使用 repr(obj) 時,會調用此方法。

當只定義 __repr__ 時的行為

如果我們註解掉 __str__ 方法,只保留 __repr__

class Cat:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return f"repr = {self.name}"

kitty = Cat('安安')
print(kitty)

輸出:

repr = 安安

行為解釋

  • 如果物件同時定義了 __str____repr__,則 print(obj) 會優先使用 __str__
  • 如果物件只定義了 __repr__,則 print(obj)repr(obj) 都會使用 __repr__

這是因為 Python 預設使用 __repr__ 作為物件的基本表示方法,__str__ 只是一個額外的覆寫選項,用於更友好的輸出。


__str____repr__ 的差異與應用場景

特性__str____repr__
用途提供易於閱讀的物件描述,供使用者查看提供正式且詳細的物件描述,供開發者調試使用
優先級print(obj)str(obj) 使用交互式解釋器或 repr(obj) 使用
預設行為若未定義,默認調用 __repr__若未定義,顯示物件的記憶體位址資訊
內容建議簡短且易懂的描述精確的資訊,儘可能重現物件的初始化狀態

原理與實現細節

為什麼 __str____repr__ 都存在?

  • 不同的目標對象
    __str__ 面向使用者,提供簡明易懂的資訊;__repr__ 面向開發者,提供詳細的技術資訊。
  • 重複使用的便利性
    當未定義 __str__ 時,Python 會自動回退使用 __repr__,避免重複定義的麻煩。

建議與最佳實踐

  1. 同時定義 __str____repr__
    • 若物件既需要對使用者友好的輸出,又需要給開發者詳細的資訊,應該同時定義兩者,並區分其內容。
  1. __repr__ 重現物件的初始化狀態
    • __repr__ 的返回值應包含足夠的資訊,以便通過執行此字串重新創建相同的物件。
  1. 簡化 __str__ 的內容
    • __str__ 應盡量簡短,避免將技術細節暴露給使用者。

總結

Python 的 __str____repr__ 方法是自定義物件字串表示的關鍵工具。

它們分別用於滿足使用者和開發者的不同需求,讓物件的輸出既友好又實用。

通過合理使用這兩個方法,我們可以讓代碼的可讀性與可調試性大幅提升,是物件導向編程中不可忽略的重要技術點。

學會正確區分與使用 __str____repr__,將讓你的 Python 編程更加精確和高效!

Similar Posts