【適合初學者】Python 變數初始化完全解析|從 None、列表、函數、類別全面涵蓋

目次

1. 簡介

Python 是一種以簡單且易讀的語法為特色的程式語言,從初學者到專業人士都有廣泛的使用。在其中,「變數的初始化」是學習 Python 時初學者最先面對的重要概念之一。 變數是指在程式中暫時儲存資料的「具名容器」。而初始化則是指為這個容器設定初始值的作業。在 Python 中,不像 C 語言或 Java 那樣需要明確指定型別,但如果不進行適當的初始化,可能會導致錯誤、程式碼的可讀性或維護性受損。 例如,「原本想將列表空初始化,但卻在跨函數時值被共享了」「用 None 初始化了,但意圖不明確導致了 bug」等問題,往往是因為對初始化的理解不足所致。 本篇文章將系統性地說明 Python 中變數的初始化方法。從基本的數值和字串初始化,到列表、字典等複雜資料型別,甚至函數和類別中的初始化注意事項,都會以初學者也能輕鬆理解的方式詳細介紹。 對於以「Python 變數 初始化」為關鍵字搜尋的使用者,本文充滿了對實務或學習有幫助的具體資訊,請務必閱讀至最後。

2. Python 中的變數初始化是什麼?

變數的初始化是什麼?

「變數的初始化」是指在程式中使用變數之前,先賦予其初始值的行為。換句話說,這是告訴程式「這個變數是用來做這種用途的」最初步驟。 例如,以下程式碼將變數 count 初始化為整數 0。
count = 0
這樣做可以讓使用變數 count 的計算或比較處理更順暢。

Python 中的初始化特點

Python 被稱為「動態型別語言」,宣告變數時不需要明確指定型別。例如,整數或字串,都可以像這樣直接使用。
number = 100        # 初始化為整數
text = "Hello"      # 初始化為字串
C 語言或 Java 中,需要先明確指定型別後才能宣告和初始化變數,但 Python 沒有這種麻煩,因此可以直覺地撰寫程式碼。 不過,這種彈性有時會適得其反,例如意外放入不預期的資料型別,或不小心使用未初始化的變數導致錯誤。

使用未初始化的變數會怎麼樣?

在 Python 中,試圖存取未初始化的變數時,會發生 NameError 錯誤。以下是其中一例。
print(user_name)
像上面這樣,在尚未為 user_name 賦值的情況下存取,就會發生下列錯誤。
NameError: name 'user_name' is not defined
為了避免這種錯誤,在使用變數前務必先初始化。

隱式初始化與顯式初始化

在 Python 中,通常是「隱式初始化」,也就是想用時直接賦值就完成了初始化。不過,為了撰寫更安全且明確的程式碼,有時建議事先使用 None 或空清單等進行「顯式初始化」。 例如:
data = None  # 值尚未確定,但明確表示未來將使用
這樣做,可以事先宣告變數的存在,讓團隊開發或日後閱讀時更容易理解。
RUNTEQ(ランテック)|超実戦型エンジニア育成スクール

3. 基本初始化方法與資料型別的範例

在 Python 中,變數的初始化非常簡單,只要賦值即可完成。在這裡,我們將介紹常用基本資料型別的初始化方法,並附上具體的程式碼範例。

3.1 數值・字串的初始化

在 Python 中初始化數值(整數・浮動小數點)或字串,只要像下面這樣賦值即可。
count = 0               # 整數的初始化

temperature = 36.5      # 浮動小數點的初始化

message = "你好"    # 字串的初始化
這些初始化特別不容易發生錯誤,而且直觀易用。數值和字串是 Python 的基本中的基本,所以要能順利處理才行。

3.2 使用 None 的初始化

當還沒有決定值,或者想要明確表示「為空」時,None 很方便。
username = None
這樣初始化後,就能「這個變數之後會被賦予某個值,但目前尚未決定」在程式碼上顯示出來。 None 類似於 null 的概念,當函數沒有返回值時等,也會被返回。經常與條件分歧結合使用。
if username is None:
    print("使用者名稱尚未設定")

3.3 列表・字典・集合等的初始化

處理多個值時,使用列表、字典、集合(set)。以下是初始化方式。
my_list = []               # 空的列表

my_dict = {}               # 空的字典

my_set = set()             # 空的集合(※ {} 會變成字典,所以注意)
各自用途不同,所以要在適當的場合區分使用。
  • 列表(list):有順序的資料集合
  • 字典(dict):由鍵值對構成的資料結構
  • 集合(set):想要保持無重複資料時使用
例如,想要儲存使用者名稱清單時用列表,使用者 ID 與名稱的對應表則用字典,已經處理過的 ID 記錄適合用集合。

3.4 元組的初始化

元組是一旦建立就無法變更的「不變資料集合」。初始化範例如下。
empty_tuple = ()                  # 空的元組

point = (10, 20)                  # 像座標的固定配對
因為不變性得到保證,所以想要將多個值作為「固定集合」處理時很方便。 注意點是,單一元素的元組需要像 (value,) 這樣加上逗號。
single = (5,)  # 這樣就成為單一元素的元組

總結:依用途進行適當的初始化

依資料種類進行適當的初始化,能夠避免錯誤並提升程式碼的可讀性。特別是列表或字典等複雜的資料結構,在與後述的函數或類別組合時會有注意點,所以在基礎階段要好好理解才行。

4. 常見的注意事項與錯誤

Python 的變數初始化看起來很簡單,但實際上對於初學者來說,有幾個容易絆倒的點。在這裡,我們將特別說明容易被忽略、容易導致實際 bug 或意外行為的「初始化陷阱」。

4.1 注意可變的預設引數

在 Python 中定義函數時,使用列表或字典作為預設引數,可能會發生意想不到的行為。 以下的程式碼,看起來似乎沒有問題。
def add_item(item, items=[]):
    items.append(item)
    return items
然而,當多次呼叫這個函數時,會發生前一次的結果被繼承的現象。
print(add_item("A"))  # ['A']
print(add_item("B"))  # ['A', 'B'] ← 意圖外的行為
這個問題是因為在函數定義時 items=[] 只被評估一次,並被重複使用
正確的寫法
在這種情況下,使用 None 來初始化,並在函數內建立列表是最安全的。
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

4.2 變數範圍與初始化的混亂

在 Python 中,全域變數與區域變數即使名稱相同,也會根據範圍被視為不同的東西。 在以下的範例中,看起來像是使用相同的 counter,但由於範圍不同,因此被視為不同的變數。
counter = 10

def increment():
    counter = counter + 1  # 會發生錯誤
    print(counter)
這個程式碼在執行時會產生 UnboundLocalError。原因是,在函數內試圖對 counter 賦值,因此 Python 將其視為「區域變數」。但是,該區域變數尚未初始化,因此發生錯誤。
正確運行的方法
  • 如果要在函數內變更值,請使用 global 關鍵字
  • 或者,設計成透過引數或回傳值來傳遞值
def increment():
    global counter
    counter += 1
    print(counter)

4.3 不注意型別的初始化陷阱

Python 是動態型別語言,因此型別會自動變更。這一方面很方便,但也可能成為 bug 的原因。
value = 5       # 整數
value = "5"     # 這次是字串
這樣的程式碼看起來會正常運作,但之後如果試圖將 value 當作數值來處理,就會發生錯誤。
result = value + 1  # TypeError: can only concatenate str (not "int") to str
對策
  • 如果想固定型別,請使用型別註解(後述)
  • 至少,在變數初始化時明確「這個變數是用來存放什麼的」

小結:了解注意事項可以防止 bug

Python 雖然是對初學者友善的語言,但「易懂性」的背後也隱藏著陷阱。特別是,可變物件的處理範圍的差異型別的曖昧性,即使在實務層級也容易成為 bug 的原因。 為了避免此類問題,不僅要掌握初始化的基本知識,事先了解容易發生的錯誤及其對策也很重要。
年収訴求

5. 函數或類別中的初始化最佳實務

函數中的變數初始化

區域變數的初始化

Python 的函數內定義的變數,會被視為該函數的區域變數。它們獨立於函數外部,如果嘗試使用未初始化的變數,會發生錯誤。
def greet():
    message = "你好"
    print(message)

greet()
因此,使用函數內變數時,務必在函數內初始化 非常重要。

安全預設引數的使用方式

如前章所述,如果在預設引數中使用可變物件(清單或字典),可能會發生意外的值共享。 安全初始化的方法,建議使用 None,並在函數內進行初始化。
def append_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items
這種風格具有高再利用性,能帶來安全且可預測的函數設計。

類別中的變數初始化(__init__ 方法)

在 Python 的類別中,生成實例時會呼叫 __init__ 方法。在此處進行實例變數的初始化。

實例變數的初始化

class User:
    def __init__(self, name):
        self.name = name
        self.age = None  # 之後預定賦值的變數也在这里初始化

user1 = User("Sato")
print(user1.name)  # → Sato
透過附加 self. 進行初始化,即可讓每個實例擁有獨有的資料。

注意類別變數的差異

Python 具有實例變數類別變數。若不理解差異就使用,可能會發生意外的資料共享。
class Sample:
    shared_list = []  # 類別變數(全實例共享)

    def __init__(self):
        self.my_list = []  # 實例變數(各實例獨立)

a = Sample()
b = Sample()

a.shared_list.append("A")
b.shared_list.append("B")

print(a.shared_list)  # → ['A', 'B']
print(b.shared_list)  # → ['A', 'B']
類別變數會被全實例共享,因此不適合用於持有狀態。如果需要每個狀態獨立的資料,務必使用 self.__init__ 中初始化。

透過初始化明確化程式碼意圖

函數或類別中的變數初始化,也是明確「此變數預定如何使用」的設計要素。適當初始化,能讓後續閱讀程式碼的人(或未來的自己)更容易理解。

6. 活用型提示進行初始化(Optional, Union)

什麼是型提示?

型提示是,在變數或函數的引數・返回值中明確指定「預計使用此型別」的機制。從 Python 3.5 開始標準支援,並可從靜態分析工具(mypy 或 Pyright)或編輯器(VS Code、PyCharm 等)獲得補全・警告的益處。
name: str = "Yamada"
age: int = 25
is_active: bool = True
如上所述,在變數名後面加上冒號(:)和型別名稱,即可明確指定型別。

使用 Optional 進行初始化

Optional 是用來表示「某變數可能為某型別或 None」的型提示。例如,對於「尚未設定,但之後可能會放入字串」的變數,可以如下使用。
from typing import Optional

username: Optional[str] = None
這與以下相同:
from typing import Union

username: Union[str, None] = None
也就是說,Optional[X]Union[X, None] 的簡寫表示。 如此寫法,可以明確表示「此變數可能處於未設定狀態(None),但預期最終會成為 str」的意圖。

使用 Union 允許多個型別

使用 Union,即可進行「此變數可採用多個型別之一」的彈性定義。
from typing import Union

data: Union[int, str] = 42
data = "文本"  # 兩者皆 OK
這在維持動態型別檢查的優點的同時,限制型別的選項,防止未預期的錯誤的目的下使用。

帶型提示的列表或字典初始化

列表或字典也可以用型提示詳細指定。
from typing import List, Dict

names: List[str] = []
user_ages: Dict[str, int] = {}
如上所述寫法,可以明確傳達「此列表僅放入字串」「此字典放入字串鍵和整數值」的規格。

型提示的效果與活用優點

  • 編輯器補全強化:候選縮減,因此打字錯誤減少
  • 有助於早期發現錯誤:可用 mypy 等事先偵測不一致
  • 可取代文件:即使是他人程式碼,也更容易理解用法
特別是初學者升級到中級者時,「意識型別的習慣」非常重要。

總結:明確初始化,讓程式碼易讀且安全

Python 是對型別不嚴格的語言,但活用型提示可大幅提升程式碼的可靠性。在初始化時使用 Optional 或 Union 明確表示意圖,即可更容易防止錯誤,並使未來的維護更輕鬆。

7. 常見問題(FAQ)

這裡,我們以「Python 變數 初始化」相關的問題,彙整了初學者常見的疑問,以問答形式呈現。每個回答中,也會一併介紹實用的程式碼範例及注意事項。

Q1. Python 中變數不指定型別會有問題嗎?

A1. 即使不指定型別也能運作,但使用型別提示會更安全。 Python 是動態型別語言,因此只需像這樣寫,就能使用變數。
age = 25        # 無型別指定(int)
name = "Satō"   # 無型別指定(str)
不過,如果之後賦值不同的型別,可能會導致意想不到的錯誤。因此,為了提升程式碼的可讀性、自動補全支援及型別檢查,建議使用型別提示(type hints)
age: int = 25

Q2. 為什麼要用 None 初始化變數?

A2. 為了明確表示「值尚未存在」。 在 Python 中,使用 None 可以清楚地表示「尚未設定值」的狀態。
result = None  # 預期之後會賦值
特別適合用於函數的返回值、可選引數,或狀態尚未確定的變數初始化。此外,使用 None 可以像 if result is None: 這樣簡潔地判斷狀態。

Q3. 清單的正確初始化方法是什麼?

A3. 空清單用 [] 初始化,但函數引數需注意。
items = []  # 一般的初始化這樣即可
不過,如果在函數的預設引數中使用 [],值會被共享,有危險。
def add(item, items=[]):  # ❌ 每次執行值會累積
    items.append(item)
    return items
正確的做法是使用 None 在函數內初始化。
def add(item, items=None):  # ✅
    if items is None:
        items = []
    items.append(item)
    return items

Q4. 類別的變數與其他實例共享值了,為什麼?

A4. 需要理解類別變數與實例變數的差異。 Python 的類別有以下兩種變數:
  • 類別變數:整個類別共享
  • 實例變數:每個實例獨立的值
class Sample:
    shared_list = []  # 類別變數(全實例共享)

    def __init__(self):
        self.my_list = []  # 實例變數(各實例獨立)

a = Sample()
b = Sample()

a.shared_list.append("A")
b.shared_list.append("B")

print(a.shared_list)  # → ['A', 'B']
print(b.shared_list)  # → ['A', 'B']
為了避免意外共享,請使用實例變數 self.變數名,並在 __init__ 內初始化。

Q5. 變數初始值使用 0""None 的區別該如何?

A5. 根據值是「未定」還是確定為「空」來區分使用。
狀態初始值的範例含意
未設定・未定None值尚未決定
確定為空0, "", []明確知道是「空」
例如,等待使用者輸入的狀態則使用 None,如果預設使用空清單則用 []。透過明確區分意圖,可以提升後續處理的安全性與可讀性。

8. 總結|Python 初始化最佳實務

這篇文章中,我們從基礎到實務應用、常見錯誤以及型別提示的使用方法,廣泛地說明了「Python 的變數初始化」。 Python 是一種動態型別的靈活語言,但相對地,「初始化的模糊性」容易導致意外的錯誤或 bug 也是其特點之一。因此,養成以下的 初始化最佳實務,將直接連結到健康的程式碼撰寫。

✅ 初始化最佳實務總結

  • 基本型別(int、str、list 等)要明確地初始化
  count = 0
  name = ""
  items = []
  • 想要明確未定義狀態時,使用 None
  result = None
  • 函式的預設引數不要使用可變型別(列表・字典等)
  def func(data=None):
      if data is None:
          data = []
  • 類別中要為每個實例以 self.變數名 進行初始化
  class User:
      def __init__(self, name):
          self.name = name
  • 使用型別提示(Optional, Union)來明確程式碼的意圖
  from typing import Optional
  age: Optional[int] = None

✍️ 給初學者的建議

在 Python 中,程式碼「能運作」與「安全・明確」是兩回事。一開始注重能運作並沒有問題,但逐步學習明確的初始化意圖和型別的使用方式,就能撰寫出 bug 較少、可靠度高的程式碼。

📘 相關主題(為了進階)

  • Python 的作用域和命名空間的理解
  • 使用 mypy 等進行型別檢查的自動化
  • 資料類別(@dataclass)來簡化初始化
  • 與 IDE(VS Code、PyCharm)聯動來活用型別補全
感謝您閱讀至最後。希望這篇文章能幫助解決「Python 變數 初始化」困擾的讀者疑問,並成為提升水平的一助。