引言

  欢迎回到Python的学习中。在前面的章节中,我们学会了使用函数来组织代码。现在,我们将进入一个更强大的概念——类(Class)。如果说函数是"工具",那么类就是"工厂",它不仅能生产工具,还能定义生产流程和产品特性。面向对象编程是现代软件开发的基石,也是理解大多数AI框架的关键。

一、类的介绍——从现实世界到代码世界

1 对象的基本概念

   在Python中,万物皆对象——从手机、电视到电脑,每个对象都拥有属性(描述特征的变量,如手机的品牌、大小)和方法(对象能执行的功能,如打电话、拍照)。我们通过"类"来创建这些对象,使用class关键字定义类,在init方法中初始化属性,并通过定义各种方法来实现对象的行为功能,从而将现实世界的事物用代码建模,使程序结构更符合我们人类的思维方式。

2、创建类

  创建类的意思是我们提前为某一类事物创建方法,就像我们之前学到的列表,列表这种类里具有append()、copy()、remove()等方法。创建类的形式为:

class 类的名字():
'''类的说明文档'''
def __init__(self,参数1,参数2,...)
    代码1
def 方法名1(参数3,参数4,...)
    代码2
def 方法名2(参数5,参数6,...)
    代码3
...

  例如我们创建一个水果类,通过__init__方法定义三个属性:水果名称、颜色和重量,并定义了三个方法:cc1()用于描述水果的基本特征,cc2()判断水果是否可食用,cc3()根据重量估算水果的热量值。

# 创建一个Fruit类
class Fruit():
    """一个表示水果的类"""
    def __init__(self, name, color, weight):    #初始化方法
        self.name = name  # 属性:水果名称
        self.color = color  # 属性:水果颜色
        self.weight = weight  # 属性:水果重量(克)

    def cc1(self):
        print(f"这是一个{self.color}色的{self.name},重量为{self.weight}克")   #描述水果

    def cc2(self):
        print(f"{self.name}已经成熟,可以食用了!")    #判断是否可以食用

    def cc3(self):
        # 估算热量,假设每克水果大约0.5卡路里
        calories = self.weight * 0.5
        print(f"这个{self.name}大约含有{calories:.1f}卡路里")

  其中__init__是一种特殊方法,创建对象时就会自动调用来始化对象的属性和设置对象的初始状态,而且第一个参数必须是 self,它代表当前创建的实例对象是由Python自动传递,而不需要手动传入。

  与函数的定义和调用类似,在我们创建一个类之后,如果我们没有执行该类的代码那么程序就会不执行该类。

3、创建对象

  在使用类时,我们需要通过调用类来创建该类的对象,创建格式为:

对象 = 类名(实参)

  简单来说类就像设计图纸,定义了对象的模板,而我们的对象就是根据图纸制造的具体产品。

在创建对象后我们可以通过对象名使用类的方法:

对象.方法名(参数)

例如我们第一个创建的水果的类:

# 创建水果实例
apple = Fruit("苹果", "红", 150)
banana = Fruit("香蕉", "黄", 100)
orange = Fruit("橙子", "橙", 120)

        # 调用方法
apple.cc1()
banana.cc2()
orange.cc3()

二、类的属性——定义对象的特征

1、属性的使用

  在面向对象的编程中,属性是描述对象特征的变量,它们在类中定义并存储对象的状态信息。在Python中,我们通常在类的__init__方法中通过self.属性名来定义和初始化实例属性,这些属性随后可以在类的任何方法中通过self进行访问和修改,每个对象实例都拥有自己独立的属性副本,存储着该对象特有的数据值。

apple = Fruit('apple', 'red', 150)
print(apple.name)
print(apple.color)
print(apple.weight) 

2、初始化其他方法

 我们创建类时__init__()初始化方法也可以调用类中其他定义的方法,例如:

# 创建一个Fruit类
class Fruit():
    """一个表示水果的类"""

    def __init__(self, name, color, weight):  # 初始化方法
        self.name = name  # 属性:水果名称
        self.color = color  # 属性:水果颜色
        self.weight = weight  # 属性:水果重量(克)

        # 在初始化时自动调用其他方法
        self.cc1()  # 创建对象时自动描述水果
        self.cc2()  # 创建对象时自动判断成熟度
        self.cc3()  # 创建对象时自动计算热量

    def cc1(self):
        print(f"这是一个{self.color}色的{self.name},重量为{self.weight}克")  # 描述水果
    def cc2(self):
        print(f"{self.name}已经成熟,可以食用了!")  # 判断是否可以食用

    def cc3(self):
        # 估算热量,假设每克水果大约0.5卡路里
        calories = self.weight * 0.5
        print(f"这个{self.name}大约含有{calories:.1f}卡路里")  # 估算热量

# 使用示例
apple = Fruit("苹果", "红色", 150)

  这里我们在初始化里调用了下面所有的方法,所以当我们创建对象是就会自动执行后面的方法。

3、属性的修改

  我们可以直接修改对象的属性:

class Fruit():
    """一个表示水果的类"""

    def __init__(self, name, color, weight):  # 初始化方法
        self.name = name  # 属性:水果名称
        self.color = color  # 属性:水果颜色
        self.weight = weight  # 属性:水果重量(克)
    def cc1(self):
        print(f"这是一个{self.color}色的{self.name},重量为{self.weight}克")  # 描述水果
    def cc2(self):
        print(f"{self.name}已经成熟,可以食用了!")  # 判断是否可以食用

    def cc3(self):
        # 估算热量,假设每克水果大约0.5卡路里
        calories = self.weight * 0.5
        print(f"这个{self.name}大约含有{calories:.1f}卡路里")  # 估算热量


a = Fruit('apple', 'red', 150)
print(a.name, a.color, a.weight)
a.name = 'banana'
a.color = 'yellow'
a.weight = 100
print(a.name, a.color, a.weight) 

三、类的继承——代码的重用与扩展

  类的继承是面向对象编程中实现代码重用和功能扩展的重要机制。它允许我们创建一个新类(子类)来继承现有类(父类)的属性和方法,子类不仅可以重用父类的代码,还能通过添加新属性和方法进行功能扩展,或通过重写父类方法来改变其行为。

1、类的继承方式

  在创建新类时,类中的class后面()的作用是继承机子的父类并不是接收参数。继承形式为:

class 子类名(父类名):
    def __init__(self,子参数):
        super().__init__(父参数)
        代码
    def 方法1()...

  这里值得注意的是新创建的类中要在()中写入父类名,父类一定要在子类前面。

例如:

class Fruit():
    """一个表示水果的类"""

    def __init__(self, name, color, weight):  # 初始化方法
        self.name = name  # 属性:水果名称
        self.color = color  # 属性:水果颜色
        self.weight = weight  # 属性:水果重量

    def cc1(self):
        print(f"这是一个{self.color}色的{self.name},重量为{self.weight}克")  # 描述水果

    def cc2(self):
        print(f"{self.name}已经成熟,可以食用了!")  # 判断是否可以食用

    def cc3(self):
        # 估算热量,假设每克水果大约0.5卡路里
        calories = self.weight * 0.5
        print(f"这个{self.name}大约含有{calories:.1f}卡路里")  # 估算热量


# 子类:橙子(继承自水果)
class Orange(Fruit):
    def __init__(self, color, weight):
        # 调用父类的初始化方法,固定名称为"橙子"
        super().__init__("橙子", color, weight)

a = Orange("橙", 200)

# 调用继承的方法
a.cc1()
a.cc2()
a.cc3()

  Apple 和 Banana 类都继承自 Fruit 类,它们继承了 name、color、weight 属性和所有方法并且我给它们各自重写了一个方法。

2、在子类中添加方法

  我们可以在子类可以添加父类没有的新方法,我们在子类橙子中添加一个产地。

class Fruit():
    """一个表示水果的类"""

    def __init__(self, name, color, weight):  # 初始化方法
        self.name = name  # 属性:水果名称
        self.color = color  # 属性:水果颜色
        self.weight = weight  # 属性:水果重量

    def cc1(self):
        print(f"这是一个{self.color}色的{self.name},重量为{self.weight}克")  # 描述水果

    def cc2(self):
        print(f"{self.name}已经成熟,可以食用了!")  # 判断是否可以食用

    def cc3(self):
        # 估算热量,假设每克水果大约0.5卡路里
        calories = self.weight * 0.5
        print(f"这个{self.name}大约含有{calories:.1f}卡路里")  # 估算热量


# 子类:橙子(继承自水果)
class Orange(Fruit):
    def __init__(self, color, weight,origin):
        # 调用父类的初始化方法,固定名称为"橙子"
        super().__init__("橙子", color, weight)
        self.origin = origin
        # 添加父类没有的新方法:显示产地

    def cc4(self):
        print(f"这个橙子产自{self.origin}")

a = Orange("橙", 200,'合肥')

# 调用继承的方法
a.cc4()

3、覆盖父类中的方法

  当我们想要对父类中的方法进行修改时,我们可以直接在子类中重新编写,在程序执行是就会自动覆盖掉父类中的方法。

class Fruit():
    """一个表示水果的类"""

    def __init__(self, name, color, weight):  # 初始化方法
        self.name = name  # 属性:水果名称
        self.color = color  # 属性:水果颜色
        self.weight = weight  # 属性:水果重量(克)

    def cc1(self):
        print(f"这是一个{self.color}色的{self.name},重量为{self.weight}克")  # 描述水果

    def cc2(self):
        print(f"{self.name}已经成熟,可以食用了!")  # 判断是否可以食用

    def cc3(self):
        # 估算热量,假设每克水果大约0.5卡路里
        calories = self.weight * 0.5
        print(f"这个{self.name}大约含有{calories:.1f}卡路里")  # 估算热量

# 子类:苹果(继承自水果)
class Apple(Fruit):
    def cc1(self):  # 重写父类方法
        print(f"这是一个{self.color}的苹果,重量为{self.weight}克,真甜")

# 子类:香蕉(继承自水果)
class Banana(Fruit):
    def cc2(self):  # 重写父类方法
        if self.color == "黄色":
            print(f"这个香蕉已经成熟,可以食用了!")
        else:
            print(f"这个香蕉还是{self.color}的,需要再放几天")

# 使用
a = Apple("苹果", "红色", 150)
b = Banana("香蕉", "绿色", 120)

a.cc1()
b.cc2()

四、导入其他文件夹里的类——模块化编程

1、导入类

  当我们后面开始开发一些较大的项目时就会发现,定义类和使用类的代码往往不在一个文件中,这就需要我们在使用方法前导入该类。

1)、首先我们在a.py里创建一个水果类:

class Fruit():
    """一个表示水果的类"""

    def __init__(self, name, color, weight):
        self.name = name
        self.color = color
        self.weight = weight

    def cc1(self):
        print(f"这是一个{self.color}色的{self.name},重量为{self.weight}克")

    def cc2(self):
        print(f"{self.name}已经成熟,可以食用了!")

    def cc3(self):
        calories = self.weight * 0.5
        print(f"这个{self.name}大约含有{calories:.1f}卡路里")

2)、我们在b.py里使用a中创建的类

1.导入文件

# 导入a1.py
import a1
# 使用导入的类
apple = a1.Fruit("苹果", "红色", 200)
apple.cc1()
apple.cc3()

2.导入文件中指定的类

# 导入a1中的Fruit类
from a1 import Fruit
# 使用导入的类
banana = Fruit("香蕉", "黄色", 120)
banana.cc1()
banana.cc3()

3.导入为文件中的全部类

# 导入a1里所有的类
from a1 import *
# 使用导入的类
banana = Fruit("香蕉", "黄色", 120)
apple = Fruit("苹果", "红色", 200)
apple.cc1()
apple.cc3()
banana.cc1()
banana.cc3()

4.我们可以给导入的类起一个别名

# 给导入a1中的Fruit类起一个fr的名字
from a1 import Fruit as fr
# 使用导入的类
apple =fr("苹果", "红色", 200)
apple.cc1()
apple.cc3()

2、在类中使用另一个类的方法

  如果我们在a2重新创建一个类需要用到a1中的方法时:

from a1 import Fruit
class Basket():
    def __init__(self):
        self.items = []

    def add_fruit(self, fruit):
        self.items.append(fruit)

    def show_fruits(self):
        for fruit in self.items:
            fruit.cc1()  # 使用Fruit类的cc1方法
apple = Fruit("苹果", "红色", 200)
a = Basket()
a.add_fruit(apple)
a.show_fruits()

五、简单案例

  让我们用今天所学的知识来完成一个简单的案例:简单的水果店管理系统

a1.py:

class Fruit():
    """水果类"""
    def __init__(self, name, color, weight, price):
        self.name = name
        self.color = color
        self.weight = weight
        self.price = price

    def cc1(self):
        print(f"{self.color}的{self.name},重量{self.weight}克")

    def cc2(self):
        print(f"{self.name}已经成熟!")

    def cc3(self):
        calories = self.weight * 0.5
        print(f"这个{self.name}大约含有{calories:.1f}卡路里")
        return calories

a2.py

from a1 import Fruit  # 导入 Fruit 类

class FruitShop():
    """水果店类"""
    def __init__(self, shop_name):
        self.shop_name = shop_name
        self.fruits = []

    def cc1(self, fruit):
        self.fruits.append(fruit)
        print(f"添加了{fruit.name}")

    def cc2(self):
        print(f"\n{self.shop_name}的水果:")
        for fruit in self.fruits:
            fruit.cc1()  # 使用 Fruit 类的 cc1 方法

    def cc3(self, fruit_name):
        for fruit in self.fruits:
            if fruit.name == fruit_name:
                self.fruits.remove(fruit)
                print(f"售出{fruit_name}")
                return True
        print(f"没有{fruit_name}")
        return False

project1.py

from a1 import Fruit
from a2 import FruitShop
from a3 import Calculator

# 创建水果
apple = Fruit("苹果", "红色", 200, 5)
banana = Fruit("香蕉", "黄色", 120, 3)

# 创建水果店
a = FruitShop("我的水果店")

# 添加水果
a.cc1(apple)
a.cc1(banana)

# 显示水果
a.cc2()

# 卖出水果
a.cc3("苹果")

# 再次显示水果
a.cc2()

  到这里我们就掌握了面向对象编程的核心概念。在下一章,我们将学习如何去操作文件。这是数据分析和AI项目中的必备技能,让我们继续加油吧!

Logo

更多推荐