關於Python的面相對象編程

Python 其實不是面向對象的語言,更像是C語言的面向過程編程的語言

但 Python 也支持 class 關鍵字來實現類的聲明與創建

但 Python 的對象更像是 JavaScript 的函數

遇到的問題 #1

— 正確的代碼

class Person:
    user_account = None
    name = None
    days = None
    months = None
    abnormal_days = 0
    total_hours = 0
    total_work_overtime = 0
    total_late_hours = 0
    def __init__(self, user_acount, name):
        self.user_account = user_acount
        self.name = name
        self.days = []
        self.months = []
        # 增加12個月的month_record 對象
        for i in range(1, 13):
            self.months.append(date_process.MonthRecord(i))
        print(len(self.months))

— 錯誤的代碼

class Person:
    user_account = None
    name = None
    days = None
    months = []
    abnormal_days = 0
    total_hours = 0
    total_work_overtime = 0
    total_late_hours = 0
    def __init__(self, user_acount, name):
        self.user_account = user_acount
        self.name = name
        self.days = []
        # 增加12個月的month_record 對象
        for i in range(1, 13):
            self.months.append(date_process.MonthRecord(i))
        print(len(self.months))

這兩段代碼的查詢在於 months 變量,在正確的代碼里,成員變量的定義里寫成了 months = None, months = [ ] 寫在了 __init__() 函數裏面, 而在錯誤的代碼里寫成了 months = [ ]。錯誤的代碼產生的影響是什麼呢?

———–

當你創建一個新的 Person 對象 first_person 時候,在開始執行 __init__() 函數的時候(即是運行到

self.user_account = user_acount

這一步的時候),months 的對象是 [ ]

當你創建第二個 Person 對象 secong_person 的時候,第二次執行 __init__() 函數的時候,months 的對象是 first_person.month(),其引用的其實同一塊內存區域的值。

這個地方非常的反直覺,造成的後果也非常大,我為了排查這個錯誤也花了很久的時間。

——— 一點猜測

只是猜測而已,沒有進行過詳細的驗證

pyhthon 的 class 其實只是一個類似JS的函數對象,這個函數有自己的內存空間,但是實際上類就像一個函數,每一次引用的的時候都是調取的同一塊內存區域,所以,Python寫類的時候,成員變量的初始化請務必寫到 __init__()函數里

———- 驗證圖片

first_person:

 

 second_person:

 

 

 

 

Tags: