Python中的类默认只能有一个构造函数,即__init__
。
但是有时候我们会有这样的需求:根据不同的参数,初始化同一个类的不同属性,即实现多个构造函数。Python提供了两种实现多个构造函数的方式:
1. 创建类方法
采用这种方式,我们需要在类中添加一个类方法,该类方法接收不同的参数并返回一个类实例。这种方式没有定义__init__
构造函数,只是利用类方法生成实例对象。
代码示例:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def from_birth_year(cls, name, birth_year):
age = datetime.date.today().year - birth_year
return cls(name, age)
p1 = Person('Tom', 18)
p2 = Person.from_birth_year('Lucy', 1990)
print(p1.name, p1.age) # Tom 18
print(p2.name, p2.age) # Lucy 31
上述代码中,首先我们定义了__init__
构造函数,接收name
和age
参数。然后我们新增了一个类方法from_birth_year
,它接收name
和birth_year
参数,并且根据birth_year
计算出年龄,最后调用Person
类的构造函数生成实例并返回。使用这种方式可以轻松根据不同的参数生成不同的实例。
2. 利用关键字参数
采用这种方式,我们可以利用Python中定义函数时可变的关键字参数,将不同的参数传入类的构造函数。通过这种方式,我们可以根据参数的不同,在构造函数中进行分支逻辑实现。这种方式在代码实现上较第一种方式复杂,但是可以覆盖更多的场景。
代码示例:
class Student:
def __init__(self, *args, **kwargs):
if len(args) == 2:
self.name = args[0]
self.age = args[1]
self.gender = kwargs.get('gender', 'unknown')
self.score = kwargs.get('score', 60)
elif len(args) == 1 and isinstance(args[0], dict):
info = args[0]
self.name = info.get('name', 'unknown')
self.age = info.get('age', 18)
self.gender = info.get('gender', 'unknown')
self.score = info.get('score', 60)
else:
self.name = kwargs.get('name', 'unknown')
self.age = kwargs.get('age', 18)
self.gender = kwargs.get('gender', 'unknown')
self.score = kwargs.get('score', 60)
s1 = Student('Tom', 18, gender='male', score=80)
s2 = Student({'name': 'Lucy', 'age': 20, 'score': 90})
s3 = Student(name='Jerry')
print(s1.name, s1.age, s1.gender, s1.score) # Tom 18 male 80
print(s2.name, s2.age, s2.gender, s2.score) # Lucy 20 unknown 90
print(s3.name, s3.age, s3.gender, s3.score) # Jerry 18 unknown 60
上述代码中,我们定义了一个Student
类,构造函数接收任意个参数。根据参数的个数和类型,我们在构造函数中进行分支逻辑,初始化不同的属性。其中第一种情况是传入了name
和age
,并且使用关键字参数初始化gender
和score
属性。第二种情况是传入了一个字典类型的参数,直接读取字典中的内容进行初始化。第三种情况是只传入了name
和age
这两个关键字参数,其余属性使用默认值进行初始化。使用这种方式可以针对不同的参数类型和内容,进行分支逻辑初始化实例。