5200.11 Class

类为所有的对象提供通用的行为,每个对象可以拥有各自的属性。

通过一个类生成一个对象,被称为实例化。

创建一个类

class Dog:
    """A simple attempt to model a dog."""
    def __init__(self, name, age):
        """Initialize name and age attributes."""
        self.name = name
        self.age = age
        
    def sit(self):
        """Simulate a dog sitting in response to a command."""
        print(f"{self.name} is now sitting.")
 
    def roll_over(self):
        """Simulate rolling over in response to a command."""
        print(f"{self.name} rolled over!")

init方法

init 方法是一个特殊的方法,函数被实例化的时候会自动运行。

方法定义中,必须要包含 self 参数,而且这个参数必须放在其他参数前面。

在 init 中,使用 self 定义的变量,可以被任何实例访问。

访问属性和方法

通过 dot notation 可以访问一个属性和方法。

my_dog.name
my_dog.sit()

设置和修改属性

  1. 通过属性直接修改
my_new_car.odometer_reading = 23
  1. 通过方法修改
my_new_car.update_odometer(23)

继承

当一个类继承另外一个类,将会得到第一个类的属性和方法。第一个类称为父类,新类称为子类。子类可以拥有自己的新的属性和方法。

基于父类生成子类的时候,需要初始化父类的 init() 方法。

super()让你可以访问父类的方法。把所有的父类属性和方法都给子类。

class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""
 
    def __init__(self, make, model, year):
        """Initialize attributes of the parent class."""
        super().__init__(make, model, year)
 
 
my_leaf = ElectricCar('nissan', 'leaf', 2024)
print(my_leaf.get_descriptive_name())

重写父类的方法

如果父类的方法不适合子类,你可以在子类写一个完全一样的方法。

class ElectricCar(Car):
    --snip--
 
    def fill_gas_tank(self):
        """Electric cars don't have gas tanks."""
        print("This car doesn't have a gas tank!")

拆分类的方法和属性

如果一个类的方法和属性越来越多。你可以进行拆分。把大型的类拆分成多个协同工作的小类

class Car:
    --snip--
 
class Battery:
    """A simple attempt to model a battery for an electric car."""
 
    def __init__(self, battery_size=40):
        """Initialize the battery's attributes."""
        self.battery_size = battery_size
 
    def describe_battery(self):
        """Print a statement describing the battery size."""
        print(f"This car has a {self.battery_size}-kWh battery.")
 
 
class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""
 
    def __init__(self, make, model, year):
        """
        Initialize attributes of the parent class.
        Then initialize attributes specific to an electric car.
        """
        super().__init__(make, model, year)
        self.battery = Battery()
 
my_leaf = ElectricCar('nissan', 'leaf', 2024)
print(my_leaf.get_descriptive_name())
my_leaf.battery.describe_battery()

import

为了让代码保持简洁,可以存在 class 到 module

from car import Car
 
my_new_car = Car('audi', 'a4', 2024)
print(my_new_car.get_descriptive_name())
 
my_new_car.odometer_reading = 23
my_new_car.read_odometer()

模块化的方法可以让主程序干净整洁,只在高的层级去关注主程序。

from car import Car, ElectricCar
 
my_mustang = Car('ford', 'mustang', 2024)
print(my_mustang.get_descriptive_name())
my_leaf = ElectricCar('nissan', 'leaf', 2024)
print(my_leaf.get_descriptive_name())

导入一个完整的模块

import car
 
my_mustang = car.Car('ford', 'mustang', 2024)
print(my_mustang.get_descriptive_name())
 
my_leaf = car.ElectricCar('nissan', 'leaf', 2024)
print(my_leaf.get_descriptive_name())

使用别名

from electric_car import ElectricCar as EC
my_leaf = EC('nissan', 'leaf', 2024)
import electric_car as ec
 
my_leaf = ec.ElectricCar('nissan', 'leaf', 2024)