python类实现多个构造函数

  • Post category:Python

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__构造函数,接收nameage参数。然后我们新增了一个类方法from_birth_year,它接收namebirth_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类,构造函数接收任意个参数。根据参数的个数和类型,我们在构造函数中进行分支逻辑,初始化不同的属性。其中第一种情况是传入了nameage,并且使用关键字参数初始化genderscore属性。第二种情况是传入了一个字典类型的参数,直接读取字典中的内容进行初始化。第三种情况是只传入了nameage这两个关键字参数,其余属性使用默认值进行初始化。使用这种方式可以针对不同的参数类型和内容,进行分支逻辑初始化实例。