Featured image of post Python 底線用法全解析:從命名慣例到魔術方法

Python 底線用法全解析:從命名慣例到魔術方法

你知道 Python 中的底線(underscore)不只是裝飾嗎?本文帶你一次搞懂 `_`、`_name`、`name_`、`__name` 與 `__name__` 的差別與用途,幫助你寫出更專業、易讀的程式碼!

⚙️ Python 底線用法全解析

你是否曾經看過 Python 程式碼中滿是底線的命名方式,像是 __init___namefor _ in range()
這些底線並不是隨便寫的,而是有約定俗成的「潛規則」,讓你能更清楚地表達變數或函式的用途與作用範圍


目錄


1️⃣ _:單底線(暫時、不重要的變數)

✅ 用法:用在不需要用到的變數上,代表「我不在乎這個值」。

1
2
for _ in range(5):
    print("Hello")  # 印出 5 次

這裡的 _ 只是個「佔位符」,不會真的被使用。

⚠ 注意:

_ 雖然可以用來存上一個結果(例如 REPL 模式下),但一般不要重複用 _ 存資料,會讓程式難以維護。


2️⃣ _name:單底線開頭(弱私有屬性)

✅ 用法:這是一種 命名慣例(naming convention),表示「這是內部用的,請不要在類別外部使用」。

1
2
3
4
5
6
class Person:
    def __init__(self):
        self._age = 30  # 弱私有

p = Person()
print(p._age)  # 雖然可以存取,但通常建議不要
  • 並不是真正的私有(private),只是提醒其他開發者「請小心使用」
  • 如果在模組中用 from module import *,開頭為 _ 的函式/變數 不會被匯入

3️⃣ name_:單底線結尾(避開保留字)

✅ 用法:當變數名稱與 Python 保留字(keyword)衝突時,可以在後面加底線。

1
class_ = "Math"  # 因為 class 是保留字

也常見於解構時命名變數避免衝突。


4️⃣ __name:雙底線開頭(名稱改寫 / name mangling)

✅ 用法:

這是 Python 提供的「名稱改寫機制(Name Mangling)」,目的是避免子類別不小心覆寫到父類別的內部變數或方法名稱

當你使用雙底線開頭命名(例如 __type),Python 會自動幫它重新命名為 _類別名稱__變數名 的格式,這樣即使在子類別中出現同名變數,也不會互相干擾。

1
2
3
4
5
6
7
class Animal:
    def __init__(self):
        self.__type = "mammal"

a = Animal()
print(a.__type)          # ❌ AttributeError: 'Animal' object has no attribute '__type'
print(a._Animal__type)   # ✅ OK,實際上變數被重新命名成 _Animal__type

🧠 為什麼 __type 不行?

當我們寫 self.__type 時,Python 在背後其實會把它改名為 self._Animal__type。這是為了保護變數不被外部或子類誤用或覆蓋

所以:

  • __type 直接取值就會報錯,因為這個名字根本不存在於物件的屬性列表中。
  • 正確的變數名已經被改成了 _Animal__type (可以透過印出 dir(a) 來查看)。也就是說,它其實是存到 self._Animal__type 這個變數裡,而不是 self.__type

📌 小提醒:

  • 在 Python 中,此改名並非真正的私有保護,它只是讓存取更困難一點。
  • 請避免濫用這個機制,通常只有在你寫大型專案、需要確保屬性不會被子類或外部干擾時才會使用。

5️⃣ __name__:雙底線包夾 / Dunder method (或是叫做魔術方法 / magic method)

✅ 用法:

這是 Python 特有的語法設計,是預留給內建功能或是魔術方法使用的。

常見例子包括:

1
2
3
4
5
def __init__(self):  # 建構子(constructor)
    pass

def __str__(self):   # 轉為字串
    pass
  • 這些方法都有特殊用途,不建議自創這類命名。
  • 最常見的例子是模組入口判斷:
1
2
if __name__ == "__main__":
    main()

代表此檔案被「直接執行」而非被匯入。


❓ 常見問題

Q1:_ 可以被當作變數名嗎?

A:可以,但不建議長時間使用,容易混淆。


Q2:我在類別裡寫 _變數,就真的變私有了嗎?

A:不是真的私有,只是開發者之間的約定俗成


Q3:可以自己定義 __myfunc__() 嗎?

A:可以,但不建議。__xxx__ 是給 Python 保留的,請避免自己創造。


💬 你最常用哪種底線寫法?

你在開發時最常遇到哪一種底線命名方式呢?
歡迎留言分享你的使用情境,或是你曾經踩過的坑 🕳️!

comments powered by Disqus
2025 Michelle's Blog. All rights reserved
Built with Hugo
Theme Stack designed by Jimmy