ZetCode

Python __init__ 方法

最后修改于 2025 年 4 月 8 日

本综合指南探讨了 Python 的 __init__ 方法,该方法是负责对象初始化的特殊方法。我们将介绍基本用法、继承、默认值、多个构造函数和实际示例。

基本定义

__init__ 方法是 Python 类中的一个特殊方法,用于初始化新创建的对象。它在对象被 __new__ 创建后自动调用。

关键特征:它必须接受 self 作为第一个参数,不返回任何内容,并用于设置对象属性的初始值。与其他语言中的构造函数不同,它不创建对象。

基本 __init__ 实现

这是最简单的实现,展示了 __init__ 如何初始化对象属性。 这演示了基本用法模式。

basic_init.py
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person = Person("Alice", 30)
print(f"{person.name} is {person.age} years old")

此示例创建一个具有 name 和 age 属性的 Person 类。 当创建一个新实例时,__init__ 方法设置这些值。

self 参数指的是正在初始化的实例。属性被赋值给 self 以使其成为实例变量。

默认参数值

__init__ 可以使用默认参数值来使某些参数成为可选参数,同时仍然允许在初始化期间进行自定义。

default_values.py
class Car:
    def __init__(self, make, model, year=2023, color="black"):
        self.make = make
        self.model = model
        self.year = year
        self.color = color
    
    def __str__(self):
        return f"{self.year} {self.make} {self.model} ({self.color})"

car1 = Car("Toyota", "Camry")
car2 = Car("Ford", "Mustang", 2022, "red")
print(car1)
print(car2)

这个 Car 类具有必需的 make 和 model 参数,以及可选的 year 和 color 参数,如果未提供,则默认为 2023 和 "black"。

默认参数使类更灵活,同时减少样板代码。 当大多数实例共享常见的默认值时,它们特别有用。

继承和 __init__

当使用继承时,可以链接 __init__ 方法以正确初始化父类属性以及子类属性。

inheritance.py
class Animal:
    def __init__(self, species):
        self.species = species
    
    def __str__(self):
        return f"I am a {self.species}"

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__("dog")
        self.name = name
        self.breed = breed
    
    def __str__(self):
        return f"{super().__str__()}, {self.name} the {self.breed}"

dog = Dog("Rex", "Labrador")
print(dog)

此示例显示如何使用 super().__init__() 正确初始化父类属性。 Dog 类扩展了 Animal,同时添加了自己的属性。

super() 函数返回一个代理对象,该对象将方法调用委托给父类。 这确保了正确的方法解析顺序。

使用 @classmethod 的多个构造函数

虽然 Python 不直接支持多个构造函数,但您可以使用 @classmethod 模拟它们以创建替代的初始化方法。

multiple_constructors.py
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    @classmethod
    def from_square(cls, side_length):
        return cls(side_length, side_length)
    
    @classmethod
    def from_dict(cls, dimensions):
        return cls(dimensions['width'], dimensions['height'])
    
    def area(self):
        return self.width * self.height

rect1 = Rectangle(4, 5)
rect2 = Rectangle.from_square(3)
rect3 = Rectangle.from_dict({'width': 2, 'height': 7})
print(rect1.area(), rect2.area(), rect3.area())

Rectangle 类显示了创建实例的三种方式:通过标准的 __init__,通过正方形工厂方法,以及从维度字典创建。

类方法提供灵活的初始化选项,同时保持一个 __init__ 方法。 每个工厂方法通过调用类构造函数返回一个新实例。

在 __init__ 中初始化集合

当初始化可变集合作为实例属性时,为每个实例创建新集合非常重要,以避免实例之间的共享状态。

collections_init.py
class ShoppingCart:
    def __init__(self, customer_name):
        self.customer_name = customer_name
        self.items = []  # New list for each instance
    
    def add_item(self, item):
        self.items.append(item)
    
    def __str__(self):
        return f"{self.customer_name}'s cart: {', '.join(self.items)}"

cart1 = ShoppingCart("Alice")
cart2 = ShoppingCart("Bob")
cart1.add_item("Book")
cart2.add_item("Shirt")
print(cart1)
print(cart2)

此示例演示了实例特定集合的正确初始化。 每个 ShoppingCart 都会获得其自己的空项目列表。

如果该列表被定义为类变量,则所有实例将共享相同的列表,从而导致在添加项目时出现意外行为。

最佳实践

资料来源

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 我自 2007 年以来一直在撰写编程文章。 至今,我已撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程