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: