python 初始化函数

云淡#风清 / 2023-05-03 / 原文

Python3中,初始化函数指的是__init__()函数,它是一个特殊的方法,用于在创建一个新对象时进行初始化操作。在这个函数中,我们可以定义一些类内部的属性和方法,并对它们进行默认赋值。

下面,让我通过一个生活中的例子来说明。

假设我们要创建一个汽车类Car,它有品牌、型号、颜色、价格等属性,并且可以加速、刹车、改变方向等操作。那么,在Python中我们可以这样定义这个类:

class Car:
    def __init__(self, brand, model, color, price):
        self.brand = brand
        self.model = model
        self.color = color
        self.price = price
        self.speed = 0
        self.direction = 'straight'

    def accelerate(self):
        self.speed += 10

    def brake(self):
        self.speed -= 10

    def turn_left(self):
        self.direction = 'left'

    def turn_right(self):
        self.direction = 'right'

在上述代码中,我们定义了一个名为Car的类,它有4个属性:品牌(brand)、型号(model)、颜色(color)和价格(price)。此外,我们还定义了__init__函数,它包含了这些属性的默认值,并初始化了两个额外的属性:速度(speed)和方向(direction)。最后,我们也定义了几个可调用的方法,用于处理与汽车相关的操作。

需要注意的是,__init__函数中第一个参数self不能省略。它表示正在创建的对象本身,并且是所有类方法的必需参数。此外,在定义其他可调用的方法时,也必须将self作为第一个参数进行传递。

初始化函数(__init__)在Python3中是一个非常重要的构造函数,用于初始化类的一些属性和方法。我们可以使用它来自定义类的默认值,并在创建新对象时执行一些特殊的操作

  1. __init__ 方法只在新对象创建时被调用一次,并不会被实例化的每个方法自动调用。因此在其它类方法中,必须显式地使用 self 参数来引用和操作对象的属性。

  2. __init__ 函数中可以为对象指定属性的默认值,但并不意味着这些属性只能有这些初始值。对象的这些属性在创建后仍然可以随时修改。

  3. __init__ 方法不能返回任何值,因为该方法的目的是初始化对象,而非生成结果。

  4. __init__ 方法中可以执行任何操作,包括打开文件、创建网络连接等等。但是,需要在函数结束时关闭打开的文件或连接,以释放资源。

  5. 可以在 __init__ 方法中向对象的属性传递值。例如,如果定义了一个名为 Car 的类,并且希望在创建汽车对象时为其指定不同的尺寸,可以编写以下代码:
    class Car:
        def __init__(self, brand, model, color, size):
            self.brand = brand
            self.model = model
            self.color = color
            self.size = size
    
    car1 = Car('Tesla', 'Model S', 'red', 'large')
    car2 = Car('Toyota', 'Camry', 'blue', 'medium')

    在上述代码中,我们定义了两个 Car 对象: car1car2car1 的尺寸为 'large',而 car2 的尺寸为 'medium'

  6. 在 __init__ 方法中,也可以为对象添加一些默认的行为。例如,如果希望在创建一个新的 Car 对象时,自动启动引擎,我们可以在 __init__ 方法中添加一个方法 start_engine() 来实现这个目标。
    class Car:
        def __init__(self, brand, model, color, size):
            self.brand = brand
            self.model = model
            self.color = color
            self.size = size
            self.start_engine()
    
        def start_engine(self):
            print("Engine started.")

    在上述代码中,__init__ 方法调用了 start_engine() 方法,因此在创建一个新的 Car 对象时,会自动启动引擎并输出 Engine started.

  7. 在 __init__ 方法中也可以引用类的其他属性和方法。例如,在 Car 类中我们定义了一个 get_description() 方法,它返回汽车的品牌、型号和颜色。我们可以在 __init__ 方法中调用这个方法,并将结果存储到新对象的一个属性中。
    class Car:
        def __init__(self, brand, model, color, size):
            self.brand = brand
            self.model = model
            self.color = color
            self.size = size
            self.description = self.get_description()
    
        def get_description(self):
            return f"{self.brand} {self.model}, {self.color}"

    在上述代码中,__init__ 方法调用了 get_description() 方法,并将返回值存储到了对象的 description 属性中。因此,在创建一个新的 Car 对象时,该对象的 description 属性会自动设置为该汽车的品牌、型号和颜色。

  8. 如果没有显式地定义 __init__ 方法,Python 将会提供一个默认的构造函数。但是,这个默认构造函数并不会为对象设置任何属性或行为,因此需要根据实际情况进行定义。

  9. __init__ 方法的名称前后均有两个下划线,这是 Python 中一种特殊的命名方式,用于指示这个方法具有特殊的作用。而且,这个方法的参数列表中必须包含 self 参数,因为 self 表示正在被创建的对象本身。

  10. 如果在 __init__ 方法中发生了错误,Python 将会抛出一个异常,并且该对象不会被正确地初始化。因此,在编写时应该注意检查和处理可能出现的错误情况。
  11. __init__ 方法也可以接受任意数量的参数,包括关键字参数。这些参数将传递给对象的 __dict__ 属性,以便可以通过属性名访问它们。例如:
  12. class Car:
        def __init__(self, **kwargs):
            for key, value in kwargs.items():
                setattr(self, key, value)
    
    car1 = Car(brand='Tesla', model='Model S', color='red', size='large')
    car2 = Car(brand='Toyota', model='Camry', color='blue', size='medium')

    在上述代码中,我们定义了一个使用 **kwargs__init__ 方法,来接收任意数量的参数,并使用 setattr() 函数将这些参数设置为对象的属性。我们可以看到,我们可以轻松地创建不同的 Car 对象,并指定不同的属性值。

  13. 最后需要注意的是,在 Python 中,初始化函数 __init__ 仅用于创建类的实例对象。如果想要在类被定义时执行某些操作(例如检查参数),则应该使用元类或类装饰器。

    元类是用于创建类的类,可以控制类的创建方式和行为。我们可以通过设置元类来自定义类的初始化过程,从而达到类似于 __init__ 方法的效果。

    类装饰器是一种特殊的函数,用于修改类的定义。我们可以使用类装饰器来添加额外的属性、方法或行为,以及检查类的定义是否合法。

  14. __init__ 方法也可以调用父类的初始化方法,以便在子类中添加新的属性或修改父类属性的默认值。我们可以使用 super() 函数来调用父类的初始化方法。例如:
    class Vehicle:
        def __init__(self, brand, model, color):
            self.brand = brand
            self.model = model
            self.color = color
    
    class Car(Vehicle):
        def __init__(self, brand, model, color, size):
            super().__init__(brand, model, color)
            self.size = size
    
    car1 = Car('Tesla', 'Model S', 'red', 'large')

    在上述代码中,Car 类继承了 Vehicle 类,并添加了一个新的属性 size。在初始化方法中,我们使用 super() 函数调用了父类的初始化方法,并传递了必要的参数。因此,在创建一个新的 Car 对象时,会自动设置其品牌、型号和颜色属性,并且自定义了 size 属性。

  15. 如果所有的子类都需要调用父类的 __init__ 方法,则应该在父类中将其定义为抽象方法(参见 Python 中的 ABC 抽象基类)。这样可以确保所有子类都正确地初始化,并在必要时提供有关如何实现 __init__ 方法的指导。
  16. 在 __init__ 方法中,也可以将一个属性设置为只读的。这样,一旦对象被创建,就不能再修改该属性的值了。这可以通过将其定义为类属性并使用 @property 装饰器来实现。例如:
    class Car:
        WHEELS = 4
    
        def __init__(self, brand, model, color):
            self.brand = brand
            self.model = model
            self.color = color
    
        @property
        def wheels(self):
            return self.WHEELS
    
    car1 = Car('Tesla', 'Model S', 'red')
    print(car1.wheels)  # 输出:4

    在上述代码中,我们将 WHEELS 属性定义为类属性,并使用 @property 装饰器将 wheels 属性设置为只读的。因此,在创建一个新的 Car 对象时,会自动设置其品牌、型号和颜色属性,并且无法更改其 wheels 属性的值。

  17. 可以通过 __slots__ 属性来限制对象可以拥有的属性。如果想要让对象具有固定的属性结构,并防止用户向对象添加任意的属性,则可以在定义类时使用 __slots__ 属性。例如:
    class Car:
        __slots__ = ['brand', 'model', 'color']
    
        def __init__(self, brand, model, color):
            self.brand = brand
            self.model = model
            self.color = color
    
    car1 = Car('Tesla', 'Model S', 'red')
    car1.size = 'large'  # 抛出 AttributeError: 'Car' object has no attribute 'size'

    在上述代码中,我们使用 __slots__ 属性将 Car 类的属性限制为 'brand''model''color',因此不能向 Car 对象添加任何其他属性。如果尝试这样做,则会引发 AttributeError 异常。