当前位置: 首页 > news >正文

如何在python中模拟重载初始化函数?

重载初始化函数

重载初始化函数,是指同一个类中定义了多个构造函数,可以通过多种不同的方法进行构造。

举例来说,如果我们创建了一个学生类,在创建学生的时候,需要提供学生的姓名以及出生日期,对于出生日期,我们考虑可以使用date对象,直接进行初始化。也可以分别使用年,月,日进行初始化。或者还可以使用例如2024-11-14日这样的时间字符串进行初始化。

在python中并没有直接的函数重载,但是,我们有多种方法可以实现类似的功能。

python实现

根据对象类型

这种方法根据传入的参数的类型不同,从而实现通过不同的方法进行解析。但是缺点是在类型多的情况下,代码变得非常复杂。

from datetime import dateclass Student:def __init__(self, name, birth_date):if isinstance(birth_date, date):self.birth_date = birth_dateelif isinstance(birth_date, str):try:year, month, day = map(int, birth_date.split("-"))self.birth_date = date(year, month, day)except ValueError:raise ValueError("日期字符串格式应为YYYY-MM-DD")elif isinstance(birth_date, tuple) and len(birth_date) == 3:year, month, day = birth_dateself.birth_date = date(year, month, day)else:raise TypeError("birth_date必须是date对象,YYYY-MM-DD格式的字符串,或(年, 月, 日)的元组")self.name = namedef __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)

使用类方法

通常情况下,使用类方法被认为是最好的实践方法,唯一的缺点在于,与常规的初始化略有不同,因此一些用户可能不能适应。

from datetime import dateclass Student:def __init__(self, name, birth_date):if not isinstance(birth_date, date):raise TypeError("birth_date必须是datetime.date类型")self.name = nameself.birth_date = birth_date@classmethoddef 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("日期字符串格式应为YYYY-MM-DD")@classmethoddef 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)

使用静态方法

如果将之前使用的类方法,改为静态方法,也是可行的,这样无需再访问类本身。

from datetime import dateclass Student:def __init__(self, name, birth_date):if not isinstance(birth_date, date):raise TypeError("birth_date必须是datetime.date类型")self.name = nameself.birth_date = birth_date@staticmethoddef 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)

但是需要注意的是,通常情况下,应该优先使用类方法而非静态方法。因为在包含继承关系的情况下,类方法可以总是保证返回的是子类的实例。而静态方法则会返回父类的实例,从而出现不符合预期的情况。

使用带默认值的参数

当提供了大量的默认值参数,初始化函数会变得复杂和难以理解,缺点与根据对象类型初始化相似。

from datetime import dateclass 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_dateelif all([year, month, day]):try:self.birth_date = date(year, month, day)except ValueError:raise ValueError("日期无效,请使用正确的年月日")else:raise ValueError("必须提供birth_date或者年月日的组合")self.name = namedef __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)

并且,使用该方法通常无法同时满足使用位置参数进行传入,因此也可以考虑禁止使用位置参数。

# 禁用位置参数
def __init__(self, name, *, birth_date=None, year=None, month=None, day=None):pass# 或者允许birth_date使用位置参数,但不允许年月日用
def __init__(self, name, birth_date=None, *, year=None, month=None, day=None):pass


http://www.mrgr.cn/news/75167.html

相关文章:

  • 嵌入式课程day14-C语言指针进阶
  • 前端垂直居中的多种实现方式及应用分析
  • 【Hadoop实训】Hive 数据操作②
  • 动手学深度学习69 BERT预训练
  • Jmeter中的定时器(二)
  • Apache ECharts
  • 下载|阿里云等联合编写的《2024大模型典型示范应用案例集》发布
  • 「Mac玩转仓颉内测版10」PTA刷题篇1 - L1-001 Hello World
  • Jdbc学习笔记(四)--PreparedStatement对象、sql攻击(安全问题)
  • 联丰策略炒股股票交易市场券商股,盘中突然拉升
  • 25京考考试时间已确定,速速查收!
  • 时序论文19|ICML24 : 一篇很好的时序模型轻量化文章,用1k参数进行长时预测
  • Linux系统编程多线程之条件变量和信号量讲解
  • java八股-垃圾回收机制-垃圾回收算法,分代回收,垃圾回收器
  • 精灵图(十八课)
  • RHCE web解析、dns配置、firewalld配置实验
  • 人工智能技术的发展历程和现状
  • 基于Spring Boot+Vue的多媒体素材管理系统的设计与实现
  • 多模态Embedding不愧是CVPR和NIPS的共同选择!这发文思路真的需要好好学习一下!
  • c语言学习16按键控制流水灯
  • 闯关leetcode——3178. Find the Child Who Has the Ball After K Seconds
  • docker安装到D盘
  • 游戏引擎学习第11天
  • 易考八股文之代理模式在AOP中如何应用?
  • Gartner发布XDR扩展检测和响应市场指南:XDR需要具备的19项功能
  • 逆向攻防世界CTF系列31-elrond32