Python训练营打卡 Day28

类的定义和方法

知识点回顾:

  1. 类的定义:菜谱的模板

    类就像是餐厅的菜谱,它定义了如何制作一道菜的步骤和所需食材。

类是对属性和方法的封装,可以理解为模板,通过对模板实例化可以实现调用这个类的属性和方法。比如创建一个随机森林类,然后就可以调用他的训练和预测方法。现在我们来学一下自己定义一个类,这会让我们对于类这个对象理解的更加深刻

ps:类的操作很多,我们这里只说一些在深度学习领域最常见和通用的

class ClassicDish:
    # 类定义
    pass

一个常见的类的定义包括了:

  • 关键字 class:就像告诉厨师要开始定义一个菜谱。

  • 类名 ClassicDish:类似于菜谱的名字,比如“宫保鸡丁”,遵循大驼峰命名法。

  • 冒号 ::表示开始定义类的内容。

  • pass:占位语句,表示类目前没有具体内容。

  • 一个初始化函数__init__(self)  

注意:注意:init左右各有两个下划线__,需要传入self这个特殊的参数。

pass占位语句:预留一个菜谱位置

假设你是一个餐厅的厨师,你正在编写一个新菜谱。你已经想好了要添加一个新的菜品,但目前还没有具体的烹饪步骤。为了确保这个菜品在菜单上有一个位置,你可以先创建一个“占位符”菜谱。

# 定义一个类,但暂时没有具体内容
class NewSpecialDish:
    pass  # 这里是一个占位符,表示这个类目前没有具体的功能

# 创建一个实例
dish = NewSpecialDish()

# 打印实例类型
print(type(dish))  # 输出: <class '__main__.NewSpecialDish'>
  • 类名 NewSpecialDish:就像是新菜谱的名字,为未来的新菜品预留了位置。

  • pass 语句:就像是在菜谱中写了一个占位符,告诉其他厨师“这里有一个新菜品,但我们还没准备好具体的烹饪步骤”。

为什么需要 pass

  1. 预留位置:使用 pass 可以确保类的名称在当前代码中占有一席之地,即使类还没有具体的功能。

  2. 避免错误:Python 需要一个缩进的代码块来定义类或函数,如果没有缩进的代码块,会抛出 IndentationErrorpass 语句可以避免这种错误。

  3. 后续开发:在后续开发中,你可以回来填充这个类的具体内容,而不必担心代码结构的问题。

        Python 通过缩进来定义代码块的结构。当解释器遇到像 def, class, if, for 这样的语句,并且后面跟着冒号 : 时,它就期望接下来会有一个或多个缩进的语句来构成这个代码块。如果它没有找到任何缩进的语句(即代码块是空的),它就无法确定这个结构的范围,因此会抛出 IndentationError。

        pass 语句的存在就是为了解决这个问题:它本身不执行任何操作,但它是一个有效的 Python 语句。所以,当你需要一个语法上存在的代码块,但又暂时不想在其中放入任何实际的逻辑时,pass 就是一个完美的占位符,它告诉解释器:“这里有一个代码块,但它什么也不做。”

类的初始化方法:准备食材

初始化方法就像厨师在烹饪之前准备好所有需要的食材。

class ClassicDish:
    def __init__(self, main_ingredient, spice_level):
        self.main_ingredient = main_ingredient  # 主食材
        self.spice_level = spice_level  # 辣度

    def prepare_ingredients(self):
        print(f"准备 {self.main_ingredient},辣度设为 {self.spice_level}")

dish = ClassicDish("鸡丁", "中辣")
dish.prepare_ingredients()

  

  • __init__ 方法:就像厨师在开始烹饪前的准备工作,创建对象时自动调用。

  • self 参数:代表当前正在处理的“这道菜”。

  • main_ingredientspice_level:是类的属性,就像菜谱中需要的主食材和辣度等级。

初始化方法又叫构造方法、特殊方法

        类有2种方法
        1. 初始化方法,

初始化方法可以理解为“准备食材”的过程。

class ClassicDish:
    def __init__(self, main_ingredient, spice_level):
        self.main_ingredient = main_ingredient  # 主食材
        self.spice_level = spice_level  # 辣度

    def prepare_ingredients(self):
        print(f"准备 {self.main_ingredient},辣度设为 {self.spice_level}")
  • 初始化方法 __init__:就像厨师在开始烹饪前的准备工作。当你点了一道菜(创建对象),厨师会先准备好所有的食材(初始化属性)。

  • self 参数:代表当前正在处理的“这道菜”。

  • main_ingredientspice_level:是类的属性,就像菜谱中需要的主食材和辣度等级。

  • 调用时:

    dish = ClassicDish("鸡丁", "中辣")
    dish.prepare_ingredients()
    # 输出:准备 鸡丁,辣度设为 中辣

        2. 普通放大

类的普通方法:烹饪步骤

普通方法就像菜谱中的具体烹饪步骤,只有在厨师执行这些步骤时才会进行实际的操作。   

除了init方法(初始化方法,又名构造方法),还包含一些普通方法(自己定义)

普通方法和init方法的差别在于,init方法是类的构造方法,当创建对象时,会自动调用init方法----只要你创建这个类对象了,这个init函数就会执行;普通方法是只有你调用类的这个方法的时候,函数才会执行。

class ClassicDish:
    def __init__(self, main_ingredient, spice_level):
        self.main_ingredient = main_ingredient
        self.spice_level = spice_level

    def cook(self):
        print(f"正在烹饪 {self.main_ingredient},辣度 {self.spice_level}")

    def serve(self):
        print(f"{self.main_ingredient} 已经做好,可以端上桌了")

dish = ClassicDish("鸡丁", "中辣")
dish.cook()   # 输出:正在烹饪 鸡丁,辣度 中辣
dish.serve()  # 输出:鸡丁 已经做好,可以端上桌了
  • cookserve 方法:是普通方法,只有在调用时才会执行。

类的继承-属性的继承、方法的继承:改良菜谱

继承就像在原有菜谱的基础上进行改良,保留原有的步骤,同时添加新的步骤或修改某些步骤。

类已经是比较优秀的封装了,封装了函数、封装了属性

正如装饰器进一步封装了函数的可复用的功能,装饰器函数封装了函数

那么有没有东西可以进一步封装类呢?这就引出了类的继承

class SpecialDish(ClassicDish):
    def __init__(self, main_ingredient, spice_level, special_topping):
        super().__init__(main_ingredient, spice_level)
        self.special_topping = special_topping  # 新增的特殊配料

    def add_special_topping(self):
        print(f"添加特殊配料:{self.special_topping}")

    def cook(self):
        super().cook()
        self.add_special_topping()

special_dish = SpecialDish("鸡丁", "微辣", "腰果")
special_dish.cook()
special_dish.serve()
  • SpecialDish:继承自 ClassicDish 类,保留了原有的属性和方法,同时添加了新的属性和方法。

  • super() 函数:用于调用父类的构造方法,确保父类的初始化逻辑被执行。

  • add_special_topping 方法:是新增的方法,用于添加特殊配料。

  • 重写 cook 方法:在原有 cook 方法的基础上增加了新的步骤。

在面向对象编程中,继承允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码复用和功能扩展。子类可以:

1. 复用父类的代码(无需重新实现)。

2. 重写父类的方法(修改或增强功能)。

3. 添加新的方法和属性(扩展功能)。

作业

题目1:定义圆(Circle)类

要求:

  1. 包含属性:半径 radius。
  2. 包含方法:
  • calculate_area():计算圆的面积(公式:πr²)。
  • calculate_circumference():计算圆的周长(公式:2πr)。
  1. 初始化时需传入半径,默认值为 1。
# 示例运行
circle = Circle(5)
print(f"半径:{circle.radius}")       # 输出:半径:5
print(f"面积:{circle.calculate_area()}")   # 输出:面积:78.54(保留两位小数)
print(f"周长:{circle.calculate_circumference()}") # 输出:周长:31.42(保留两位小数)

import math

class Circle:
    def __init__(self, radius=1):
        self.radius = radius

    def calculate_area(self):
        try:
            if self.radius < 0:
                return 0
            return math.pi * self.radius ** 2
        except TypeError:
            return 0

    def calculate_circumference(self):
        try:
            if self.radius < 0:
                return 0
            return 2 * math.pi * self.radius
        except TypeError:
            return 0

# 示例运行
circle = Circle(5)
print(f"半径:{circle.radius}")  # 输出:半径:5
print(f"面积:{circle.calculate_area():.2f}")  # 输出:面积:78.54(保留两位小数)
print(f"周长:{circle.calculate_circumference():.2f}")  # 输出:周长:31.42(保留两位小数)

题目2:定义长方形(Rectangle)类

  1. 包含属性:长 length、宽 width。
  2. 包含方法:
  • calculate_area():计算面积(公式:长×宽)。
  • calculate_perimeter():计算周长(公式:2×(长+宽))。 is_square() 方法,判断是否为正方形(长 == 宽)。
  1. 初始化时需传入长和宽,默认值均为 1。
rect = Rectangle(4, 6)
print(f"长:{rect.length}, 宽:{rect.width}")  # 输出:长:4, 宽:6
print(f"面积:{rect.calculate_area()}")      # 输出:面积:24
print(f"周长:{rect.calculate_perimeter()}")  # 输出:周长:20
print(f"是否为正方形:{rect.is_square()}")    # 输出:是否为正方形:False

square = Rectangle(5, 5)
print(f"是否为正方形:{square.is_square()}")  # 输出:是否为正方形:True

class Rectangle:
    def __init__(self, length=1, width=1):
        self.length = length
        self.width = width

    def calculate_area(self):
        try:
            if self.length < 0 or self.width < 0:
                return 0
            return self.length * self.width
        except TypeError:
            return 0

    def calculate_perimeter(self):
        try:
            if self.length < 0 or self.width < 0:
                return 0
            return 2 * (self.length + self.width)
        except TypeError:
            return 0

    def is_square(self):
        return self.length == self.width

# 示例运行
rect = Rectangle(4, 6)
print(f"长:{rect.length}, 宽:{rect.width}")  # 输出:长:4, 宽:6
print(f"面积:{rect.calculate_area()}")  # 输出:面积:24
print(f"周长:{rect.calculate_perimeter()}")  # 输出:周长:20
print(f"是否为正方形:{rect.is_square()}")  # 输出:是否为正方形:False

square = Rectangle(5, 5)
print(f"是否为正方形:{square.is_square()}")  # 输出:是否为正方形:True

题目3:图形工厂

创建一个工厂函数 create_shape(shape_type, *args),根据类型创建不同图形对象:图形工厂(函数或类)

shape_type="circle":创建圆(参数:半径)。

shape_type="rectangle":创建长方形(参数:长、宽)。

shape1 = create_shape("circle", 5)
print(shape1.calculate_circumference())  # 输出:31.42

shape2 = create_shape("rectangle", 3, 4)
print(shape2.is_square())                # 输出:False

import math

class Circle:
    def __init__(self, radius=1):
        self.radius = radius

    def calculate_area(self):
        try:
            if self.radius < 0:
                return 0
            return math.pi * self.radius ** 2
        except TypeError:
            return 0

    def calculate_circumference(self):
        try:
            if self.radius < 0:
                return 0
            return 2 * math.pi * self.radius
        except TypeError:
            return 0


class Rectangle:
    def __init__(self, length=1, width=1):
        self.length = length
        self.width = width

    def calculate_area(self):
        try:
            if self.length < 0 or self.width < 0:
                return 0
            return self.length * self.width
        except TypeError:
            return 0

    def calculate_perimeter(self):
        try:
            if self.length < 0 or self.width < 0:
                return 0
            return 2 * (self.length + self.width)
        except TypeError:
            return 0

    def is_square(self):
        return self.length == self.width


def create_shape(shape_type, *args):
    if shape_type == "circle":
        if len(args) == 1:
            return Circle(args[0])
        else:
            raise ValueError("Circle requires exactly one argument: radius")
    elif shape_type == "rectangle":
        if len(args) == 2:
            return Rectangle(args[0], args[1])
        else:
            raise ValueError("Rectangle requires exactly two arguments: length and width")
    else:
        raise ValueError("Unsupported shape type")


# 测试
shape1 = create_shape("circle", 5)
print(shape1.calculate_circumference())  # 输出:31.41592653589793

shape2 = create_shape("rectangle", 3, 4)
print(shape2.is_square())  # 输出:False

@浙大疏锦行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值