python模擬重載初始化函數(shù)的方法詳解
重載初始化函數(shù)
重載初始化函數(shù),是指同一個類中定義了多個構(gòu)造函數(shù),可以通過多種不同的方法進(jìn)行構(gòu)造。
舉例來說,如果我們創(chuàng)建了一個學(xué)生類,在創(chuàng)建學(xué)生的時候,需要提供學(xué)生的姓名以及出生日期,對于出生日期,我們考慮可以使用date對象,直接進(jìn)行初始化。也可以分別使用年,月,日進(jìn)行初始化。或者還可以使用例如2024-11-14日這樣的時間字符串進(jìn)行初始化。
在python中并沒有直接的函數(shù)重載,但是,我們有多種方法可以實現(xiàn)類似的功能。
python實現(xiàn)
根據(jù)對象類型
這種方法根據(jù)傳入的參數(shù)的類型不同,從而實現(xiàn)通過不同的方法進(jìn)行解析。但是缺點是在類型多的情況下,代碼變得非常復(fù)雜。
from datetime import date
class Student:
def __init__(self, name, birth_date):
if isinstance(birth_date, date):
self.birth_date = birth_date
elif isinstance(birth_date, str):
try:
year, month, day = map(int, birth_date.split("-"))
self.birth_date = date(year, month, day)
except ValueError:
raise ValueError("日期字符串格式應(yīng)為YYYY-MM-DD")
elif isinstance(birth_date, tuple) and len(birth_date) == 3:
year, month, day = birth_date
self.birth_date = date(year, month, day)
else:
raise TypeError("birth_date必須是date對象,YYYY-MM-DD格式的字符串,或(年, 月, 日)的元組")
self.name = name
def __str__(self):
return f"Student(name={self.name}, birth_date={self.birth_date})"
student1 = Student("sagegrass", date(2011, 11, 11))
student2 = Student("sagegrass", "2011-11-11")
student3 = Student("sagegrass", (2011, 11, 11))
print(student1)
print(student2)
print(student3)使用類方法
通常情況下,使用類方法被認(rèn)為是最好的實踐方法,唯一的缺點在于,與常規(guī)的初始化略有不同,因此一些用戶可能不能適應(yīng)。
from datetime import date
class Student:
def __init__(self, name, birth_date):
if not isinstance(birth_date, date):
raise TypeError("birth_date必須是datetime.date類型")
self.name = name
self.birth_date = birth_date
@classmethod
def from_string(cls, name, birth_date_str):
try:
year, month, day = map(int, birth_date_str.split("-"))
birth_date = date(year, month, day)
return cls(name, birth_date)
except ValueError:
raise ValueError("日期字符串格式應(yīng)為YYYY-MM-DD")
@classmethod
def from_year_month_day(cls, name, year, month, day):
try:
birth_date = date(year, month, day)
return cls(name, birth_date)
except ValueError:
raise ValueError("日期無效,請使用正確的年月日")
def __str__(self):
return f"Student(name={self.name}, birth_date={self.birth_date})"
student1 = Student("sagegrass", date(2011, 11, 11))
student2 = Student.from_string("sagegrass", "2011-11-11")
student3 = Student.from_year_month_day("sagegrass", 2011, 11, 11)
print(student1)
print(student2)
print(student3)使用靜態(tài)方法
如果將之前使用的類方法,改為靜態(tài)方法,也是可行的,這樣無需再訪問類本身。
from datetime import date
class Student:
def __init__(self, name, birth_date):
if not isinstance(birth_date, date):
raise TypeError("birth_date必須是datetime.date類型")
self.name = name
self.birth_date = birth_date
@staticmethod
def from_year_month_day(name, year, month, day):
try:
birth_date = date(year, month, day)
return Student(name, birth_date)
except ValueError:
raise ValueError("日期無效,請使用正確的年月日")
def __str__(self):
return f"Student(name={self.name}, birth_date={self.birth_date})"
student = Student.from_year_month_day("sagegrass", 2011, 11, 11)
print(student)但是需要注意的是,通常情況下,應(yīng)該優(yōu)先使用類方法而非靜態(tài)方法。因為在包含繼承關(guān)系的情況下,類方法可以總是保證返回的是子類的實例。而靜態(tài)方法則會返回父類的實例,從而出現(xiàn)不符合預(yù)期的情況。
使用帶默認(rèn)值的參數(shù)
當(dāng)提供了大量的默認(rèn)值參數(shù),初始化函數(shù)會變得復(fù)雜和難以理解,缺點與根據(jù)對象類型初始化相似。
from datetime import date
class Student:
def __init__(self, name, birth_date=None, year=None, month=None, day=None):
if birth_date is not None:
if not isinstance(birth_date, date):
raise TypeError("birth_date必須是datetime.date類型")
self.birth_date = birth_date
elif all([year, month, day]):
try:
self.birth_date = date(year, month, day)
except ValueError:
raise ValueError("日期無效,請使用正確的年月日")
else:
raise ValueError("必須提供birth_date或者年月日的組合")
self.name = name
def __str__(self):
return f"Student(name={self.name}, birth_date={self.birth_date})"
student1 = Student("sagegrass", birth_date=date(2011, 11, 11))
student2 = Student("sagegrass", year=2011, month=11, day=11)
print(student1)
print(student2)并且,使用該方法通常無法同時滿足使用位置參數(shù)進(jìn)行傳入,因此也可以考慮禁止使用位置參數(shù)。
# 禁用位置參數(shù)
def __init__(self, name, *, birth_date=None, year=None, month=None, day=None):
pass
# 或者允許birth_date使用位置參數(shù),但不允許年月日用
def __init__(self, name, birth_date=None, *, year=None, month=None, day=None):
pass到此這篇關(guān)于python模擬重載初始化函數(shù)的方法詳解的文章就介紹到這了,更多相關(guān)python重載初始化函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python FastAPI+Celery+RabbitMQ實現(xiàn)分布式圖片水印處理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Python FastAPI如何結(jié)合Celery以及RabbitMQ實現(xiàn)簡單的分布式圖片水印處理系統(tǒng),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04
python使用paramiko實現(xiàn)ssh的功能詳解
這篇文章主要介紹了python使用paramiko實現(xiàn)ssh的功能詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
Python多線程與多進(jìn)程相關(guān)知識總結(jié)
進(jìn)程(process)和線程(thread)是操作系統(tǒng)的基本概念,是操作系統(tǒng)程序運(yùn)行的基本單元,本文簡要介紹進(jìn)程和線程的概念以及Python中的多進(jìn)程和多線程.需要的朋友可以參考下2021-05-05
python實現(xiàn)校園網(wǎng)自動登錄的示例講解
下面小編就為大家分享一篇python實現(xiàn)校園網(wǎng)自動登錄的示例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04
jupyter notebook保存文件默認(rèn)路徑更改方法匯總(親測可以)
安裝Anaconda后,新建文件的默認(rèn)存儲路徑一般在C系統(tǒng)盤,那么路徑是什么呢?如何更改jupyter notebook保存文件默認(rèn)路徑呢?今天小編就這一問題通過兩種方法給大家講解,需要的朋友跟隨小編一起看看吧2021-06-06
jupyter 實現(xiàn)notebook中顯示完整的行和列
這篇文章主要介紹了jupyter 實現(xiàn)notebook中顯示完整的行和列,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04

