目录

  • 一、类的概念
  • 二、定义类
  • 三、创建对象并进行访问
  • 四、修改属性的值
  • 方法一:句点表示法直接访问并修改
  • 方法二:通过方法进行修改
  • 五、继承
  • 继承父类属性和方法
  • 重写父类方法
  • 六、将实例用作属性
  • 七、导入类
  • 导入单个类
  • 从一个模块中导入多个类
  • 导入整个模块
  • 导入模块中的所有类
  • 八、一些代码编写规范
  • 遇到看不明白的地方,欢迎在评论中留言呐,一起讨论,一起进步!

    本文参考:《Python编程:从入门到实践(第2版)》

    一、类的概念

    是是一种定义对象结构的方式,它包含了属性(变量)和行为(方法),这些行为的代码可以操作这些变量。类可以看作是一个模板,用来创建具有相同属性和方法的对象实例。通过类,我们可以实例化出各种各样具体的对象

    二、定义类

    定义一个类非常简单,只需要使用 class 关键字,后面跟着类名(首字母大写),然后是冒号。类体中的代码块定义了类的属性和方法。

    class Car:
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
    
        def description(self):
            return f"{self.year} {self.make} {self.model}"
    

    在上面的例子中,Car 是一个类,它有三个属性:makemodelyear

    __init__(开头结尾都有两个下划线)方法是一个特殊的方法,被称为类的构造器,它在创建类的新实例时自动调用。在这个方法中,形参 self 必不可少。

    __init__ 方法中,我们可以指定属性的默认值,下面来添加一个名为 odometer_reading 的属性,其初始值总是为 0:

    class Car:
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer_reading = 0  # 指定属性的默认值
        ...
    

    注:方法的第一个参数总是 self,它代表当前对象的实例。

    三、创建对象并进行访问

    一旦定义了一个类,就可以使用它来创建对象。在Python中,我们使用 ClassName() 的方式来创建一个类的新实例,这时会自动调用方法 __init__,并使用提供的值来设置对象的属性。这种方式最后会返回一个对象的实例,我们再将这个实例赋值给一个变量(小写字母表示)进行存储。

    my_car = Car("Toyota", "Corolla", 2020)
    

    要访问实例的属性,使用句点表示法:对象变量.属性名

    print(my_car.year)
    

    要调用实例的方法,也使用句点表示法:对象变量.方法名()

    print(my_car.description())
    

    我们可以根据一个类创建任意数量的实例,这些实例都存储在不同的变量中,互不影响。

    四、修改属性的值

    方法一:句点表示法直接访问并修改

    class Car:
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer_reading = 0  # 指定属性的默认值
        ... 
    
    my_car = Car("Toyota", "Corolla", 2020)
    print(my_car.description())
    my_car.odometer_reading = 23  # 直接修改属性的值
    print(my_car.description())
    

    执行结果:

    方法二:通过方法进行修改

    class Car:
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer_reading = 0
    
        def update_odometer(self, mileage):
            """将里程表读数设置为指定的值。"""
            self.odometer_reading = mileage
    
        def description(self):
            return f"{self.year} {self.make} {self.model} {self.odometer_reading}"
    
    
    my_car = Car("Toyota", "Corolla", 2020)
    print(my_car.description())
    my_car.update_odometer(99)  # 通过方法修改
    print(my_car.description())
    

    执行结果:

    五、继承

    继承父类属性和方法

    编写类时,并非总是要从空白开始。如果要编写的类是另一个现成类的特殊版本,可使用继承。一个类继承另一个类时,将自动获得另一个类的所有属性和方法。原有的类称为父类,而新类称为子类。子类继承了父类的所有属性和方法,同时还可以定义自己的属性和方法。

    在既有类的基础上编写新类时,通常要调用父类的方法super().init()。这将初始化在父类__init__()方法中定义的所有属性,从而让子类包含这些属性。

    super() 是一个特殊函数,让子类能够调用父类的方法。父类也称为超类 (superclass),名称 super 由此而来。

    在下面的例子中,ElectricCar 类继承了 Car 类,并添加了一个新的属性 battery_size 和相应的方法。

    class Car:
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer_reading = 0
        ...
    
    class ElectricCar(Car):  # 注意格式
        def __init__(self, make, model, year, battery_size):
            super().__init__(make, model, year)  # 要调用父类的__init__()方法
            self.battery_size = battery_size
    
        def display_battery(self):
            return f"Battery size: {self.battery_size} kWh"
    

    👉 这里有几点需要注意:

    1. 创建子类时,父类必须包含在当前文件中,且位于子类前面
    2. 定义子类时,必须在圆括号内指定父类的名称

    重写父类方法

    重写父类的方法时,可在子类中定义一个与要重写的父类方法同名的方法。这样,Python 将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。

    假设 Car 类有一个名为 fill_gas_tank() 的方法,它对全电动汽车来说毫无意义,因此你可能想重写它。下面演示了一种重写方式:

    class ElectricCar(Car):
        -...
    
        def fill_gas_tank(self):
            """电动汽车没有油箱。"""
            print("This car doesn't need a gas tank!")
        ...
    

    现在,如果有人对电动汽车调用方法 fill_gas_tank(),Python 将忽略 Car 类中的方法 fill_gas_tank(),转而运行上述代码。

    使用继承时,可让子类保留从父类那里继承而来的精华,并剔除不需要的糟粕。

    六、将实例用作属性

    有时可能需要将类的一部分提取出来,作为一个独立的类,这样可以将大型类拆分成多个协同工作的小类。

    class Car:
        def __init__(self, make, model, year):
            self.make = make
            self.model = model
            self.year = year
            self.odometer_reading = 0
    
        def update_odometer(self, mileage):
            """将里程表读数设置为指定的值。"""
            self.odometer_reading = mileage
    
        def description(self):
            return f"{self.year} {self.make} {self.model} {self.odometer_reading}"
    
    class Battery:
        """一次模拟电动汽车电瓶的简单尝试。"""
        def __init__(self,battery_size=75):
            """初始化电瓶的属性。"""
            self.battery_size = battery_size
    
        def describe_battery(self):
            """打印一条描述电瓶容量的消息。"""
            print(f"This car has a {self.battery_size}-kWh battery.")
    
    class ElectricCar(Car):
        """电动汽车的独特之处。"""
        def __init__(self,make,model,year):
            """
            初始化父类的属性。
            再初始化电动汽车特有的属性。
            """
            super().__init__(make,model,year)
            self.battery = Battery()  # 将实例用作属性
    
    my_tesla = ElectricCar('tesla','model s',2019)
    my_tesla.battery.describe_battery()
    

    执行结果:

    七、导入类

    Python 允许将类存储在模块中,然后在主程序中导入所需的模块。

    导入单个类

    car.py:(模块,文件名 car 就是模块名)

    """一个可用于表示汽车的类。"""
    class Car:
        """一次模拟汽车的简单尝试。"""
    
        def __init__(self,make,model,year):
            """初始化描述汽车的属性。"""
            self.make = make
            self.model = model
            self.year = year
            self.odometer_reading = 0
    
        def get_descriptive_name(self):
            """返回整洁的描述性名称。"""
            long_name = f"{self.year} {self.make} {self.model}"
            return long_name.title()
    
        def read_odometer(self):
            """打印一条消息,指出汽车的里程。"""
            print(f"This car has {self.odometer_reading} miles on it.")
    
        def update_odometer(self,mileage):
            """
            将里程表读数设置为指定的值。
            拒绝将里程表往回调。
            """
            if mileage >= self.odometer_reading:
                self.odometer_reading = mileage
            else:
                print("You can't roll back an odometer!")
    
        def increment_odometer(self,miles):
            """将里程表读数增加指定的量。"""
            self.odometer_reading += miles
    

    my_car.py:(主程序)

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

    执行结果:

    从一个模块中导入多个类

    car.py:(模块)

    """一组用于表示燃油汽车和电动汽车的类。"""
    class Car:
        """一次模拟汽车的简单尝试。"""
    
        def __init__(self,make,model,year):
            """初始化描述汽车的属性。"""
            self.make = make
            self.model = model
            self.year = year
            self.odometer_reading = 0
    
        def get_descriptive_name(self):
            """返回整洁的描述性名称。"""
            long_name = f"{self.year} {self.make} {self.model}"
            return long_name.title()
    
        def read_odometer(self):
            """打印一条消息,指出汽车的里程。"""
            print(f"This car has {self.odometer_reading} miles on it.")
    
        def update_odometer(self,mileage):
            """
            将里程表读数设置为指定的值。
            拒绝将里程表往回调。
            """
            if mileage >= self.odometer_reading:
                self.odometer_reading = mileage
            else:
                print("You can't roll back an odometer!")
    
        def increment_odometer(self,miles):
            """将里程表读数增加指定的量。"""
            self.odometer_reading += miles
    
    class Battery:
        """一次模拟电动汽车电瓶的简单尝试。"""
    
        def __init__(self,battery_size=75):
            """初始化电瓶的属性。"""
            self.battery_size = battery_size
    
        def describe_battery(self):
            """打印一条描述电瓶容量的消息。"""
            print(f"This car has a {self.battery_size}-kWh battery.")
    
        def get_range(self):
            """打印一条描述电瓶续航里程的消息。"""
            if self.battery_size == 75:
                range = 260
            elif self.battery_size == 100:
                range = 315
    
            print(f"This car can go about {range} miles on a full charge.")
    
    class ElectricCar(Car):
        """模拟电动汽车的独特之处。"""
    
        def __init__(self,make,model,year):
            """
            初始化父类的属性。
            再初始化电动汽车特有的属性。
            """
            super().__init__(make,model,year)
            self.battery = Battery()
    

    my_cars.py:(主程序)

    from car import Car,ElectricCar  # 多个类用逗号分隔
    
    my_beetle = Car('volkswagen','beetle',2019)
    print(my_beetle.get_descriptive_name())
    
    my_tesla = ElectricCar('tesla','roadster',2019)
    print(my_tesla.get_descriptive_name())
    

    执行结果:

    导入整个模块

    还可以导入整个模块,再使用句点表示法访问需要的类
    my_cars.py:(主程序)

    import car
    
    my_beetle = car.Car('volkswagen','beetle',2019)  # 句点表示法
    print(my_beetle.get_descriptive_name())
    
    my_tesla = car.ElectricCar('tesla','roadster',2019)  # 句点表示法
    print(my_tesla.get_descriptive_name())
    

    导入模块中的所有类

    from module_name import *
    

    不推荐使用这种导入方式。这种方式可能引发名称方面的同名问题,难以诊断。

    需要从一个模块中导入很多类时,最好导入整个模块,并使用 模块名.类名 语法来访问类

    八、一些代码编写规范

    类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。
    实例名模块名都采用小写格式,并在单词之间加上下划线

    对于每个类,都应紧跟在类定义后面包含一个文档字符串,简要地描述类的功能。
    每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。

    在类中,可使用一个空行来分隔方法。
    而在模块中,可使用两个空行来分隔类。

    先编写导入标准库模块的 import 语句,再添加一个空行,然后编写导入自己编写的模块的 import 语句

    作者:诸葛思颖

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python 基础:类

    发表回复