熟悉Java的同学都知道Java中有重载的这个概念,简单来说就是Java的一个类中允许有同名方法出现,只要方法的参数个数、参数名各不相同即可,如下所示:
public class People {
public People(){
System.out.println("主类无参构造方法");
}
public People(String name) {
System.out.println("子类有参构造方法: " + name);
}
public static void main(String[] args) {
People p1 = new People();
People p2 = new People("小王");
}
}
结果:
主类无参构造方法
子类有参构造方法: 小王
很明显,上述例子中定义了两个相同名称的构造方法,唯一的区别就是一个有参、一个无参。实例化的时候根据是否传参来决定调用哪个方法。再举个Java源码中的例子:
如截图所示,这个是HashMap的源码结构,一共4个构造方法。说完Java,那么Python呢?Python是否支持这种重载的方式呢?我们可以来试一下。
class User:
def __init__(self) -> None:
print("无参构造")
def __init__(self, name) -> None:
self.name = name
print(f"有参构造 {self.name}")
if __name__ == "__main__":
user = User()
# 运行结果:
Traceback (most recent call last):
File "/var/T/tempCodeRunnerFile.python", line 22, in <module>
user = User()
TypeError: __init__() missing 1 required positional argument: 'name'
报错信息提示,__init__()构造方法需要name这个参数,由此可见,Python并不支持这种方式,它会使用最后一个定义的方法进行覆盖,也就是说,生效的构造方法始终是最后一个定义的。那么Python有没有类似Java中这种重载机制呢?答案是有的,就是使用*arg, **kwargs,还是举例说明:
class User:
def __init__(self, *arg, **kwargs) -> None:
if arg:
print(f"*arg + {type(arg)} + {arg}")
elif kwargs:
print(f"*kwarg + {type(kwargs)} + {kwargs}")
else:
print("无参")
if __name__ == "__main__":
user1 = User()
user2 = User("有参数")
user3 = User(name="有参数")
# 运行结果:
无参
*arg + <class 'tuple'> + ('有参数',)
*kwarg + <class 'dict'> + {'name': '有参数'}
如上,定义构造方法时只定义一个,但实际使用时却可以根据需要灵活传参。需要注意的是使用*arg时,传参内容会组成一个元组,而使用**kwargs时传参会组成一个字典。
就先说这么多吧,算是抛砖引玉了,有需要的同学可以在自己的代码中尝试下!