Day 32 类的定义和方法

@浙大疏锦行

在 Python 中,类(Class) 是面向对象编程(OOP)的核心,用于封装属性(数据)方法(操作数据的函数),实现代码的模块化、复用性和可维护性。对象(Object)是类的实例,类是对象的 "模板"。

一、类的核心概念

  1. 类(Class) :定义对象的共同属性和行为,如 Circle 类定义圆的半径和计算面积的方法。
  2. 对象(Instance) :类的具体实例,如 circle1 = Circle(5) 生成一个半径为 5 的圆对象。
  3. 属性(Attribute) :类 / 对象存储的数据,分为实例属性 (每个对象独有)和类属性(所有对象共享)。
  4. 方法(Method) :类中定义的函数,分为实例方法类方法静态方法,用于操作属性。

二、类的定义:基础语法

使用 class 关键字定义类,类名通常采用 大驼峰命名法 (如 PersonRectangle)。

1. 最简类定义

复制代码
class Person:
    """这是一个人类的类,用于描述人的基本信息和行为"""
    # 类属性:所有实例共享
    species = "Human"

    # 初始化方法:创建实例时自动调用,初始化实例属性
    def __init__(self, name, age):
        # 实例属性:每个对象独有
        self.name = name
        self.age = age

    # 实例方法:第一个参数必须是 self(代表当前实例)
    def introduce(self):
        return f"我叫{self.name},今年{self.age}岁"

2. 关键语法解析

元素 作用
class Person: 定义名为 Person 的类
species = "Human" 类属性 ,所有 Person 实例共享该属性
__init__(self, name, age) 构造方法 / 初始化方法,创建实例时自动执行,用于初始化实例属性
self 实例方法的第一个参数,代表当前对象本身,通过 self 访问实例属性和方法
self.name = name 给当前实例绑定 name 属性
def introduce(self): 实例方法,用于描述对象的行为

三、类的实例化:创建对象

通过 类名(参数) 创建类的实例(对象),参数需与 __init__ 方法匹配。

python

运行

复制代码
# 创建 Person 类的两个实例
person1 = Person("Alice", 18)
person2 = Person("Bob", 20)

# 访问实例属性
print(person1.name)  # 输出:Alice
print(person2.age)   # 输出:20

# 访问类属性(实例和类都能访问)
print(person1.species)  # 输出:Human
print(Person.species)   # 输出:Human

# 调用实例方法
print(person1.introduce())  # 输出:我叫Alice,今年18岁
print(person2.introduce())  # 输出:我叫Bob,今年20岁

四、类的方法:三大类型

类中的方法分为 实例方法类方法静态方法,三者的核心区别在于参数和适用场景。

1. 实例方法(最常用)

  • 定义 :第一个参数必须是 self,代表当前实例。

  • 调用 :通过实例对象 调用,自动传入 self

  • 作用:操作实例属性,实现对象的行为。

    class Circle:
    pi = 3.14159 # 类属性:圆周率

    复制代码
      def __init__(self, radius):
          self.radius = radius  # 实例属性:半径
    
      # 实例方法:计算面积
      def calculate_area(self):
          return self.pi * self.radius ** 2

    实例化

    circle = Circle(5)
    print(circle.calculate_area()) # 输出:78.53975

2. 类方法

  • 定义 :用装饰器 @classmethod 标记,第一个参数是 cls,代表类本身

  • 调用 :通过实例 调用,自动传入 cls

  • 作用:操作类属性,不依赖实例属性,常用于创建实例的替代构造方法。

    class Person:
    species = "Human"

    复制代码
      def __init__(self, name, age):
          self.name = name
          self.age = age
    
      # 类方法:修改类属性
      @classmethod
      def change_species(cls, new_species):
          cls.species = new_species

    通过类调用类方法

    Person.change_species("Homo sapiens")
    print(Person.species) # 输出:Homo sapiens

    通过实例调用类方法(效果相同)

    person = Person("Charlie", 25)
    person.change_species("Human Being")
    print(Person.species) # 输出:Human Being

类方法的典型场景:替代构造方法
复制代码
class Rectangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

    # 类方法:从正方形边长创建矩形(替代构造)
    @classmethod
    def from_square(cls, side):
        return cls(side, side)  # cls 等价于 Rectangle

# 正常创建矩形
rect1 = Rectangle(10, 5)
print(rect1.area())  # 输出:50

# 通过类方法创建正方形(特殊矩形)
square = Rectangle.from_square(6)
print(square.area())  # 输出:36

3. 静态方法

  • 定义 :用装饰器 @staticmethod 标记,无默认参数 (不需要 selfcls)。

  • 调用 :通过实例调用。

  • 作用:与类相关但不依赖类属性 / 实例属性的工具函数,逻辑上属于类。

    class MathUtils:
    # 静态方法:判断一个数是否为偶数
    @staticmethod
    def is_even(num):
    return num % 2 == 0

    通过类调用静态方法

    print(MathUtils.is_even(4)) # 输出:True
    print(MathUtils.is_even(5)) # 输出:False

    通过实例调用静态方法(效果相同)

    utils = MathUtils()
    print(utils.is_even(6)) # 输出:True

4. 三种方法的对比

方法类型 装饰器 第一个参数 调用方式 适用场景
实例方法 self(实例) 实例。方法 () 操作实例属性
类方法 @classmethod cls(类) 类。方法 () / 实例。方法 () 操作类属性、替代构造
静态方法 @staticmethod 类。方法 () / 实例。方法 () 独立工具函数,与类相关但无属性依赖

五、类的继承

继承是面向对象的核心特性,允许子类继承父类的属性和方法,实现代码复用。

复制代码
# 父类
class Animal:
    def __init__(self, name):
        self.name = name

    def eat(self):
        print(f"{self.name}正在吃东西")

# 子类:继承 Animal
class Dog(Animal):
    # 子类可以扩展自己的方法
    def bark(self):
        print(f"{self.name}正在汪汪叫")

# 实例化子类
dog = Dog("旺财")
dog.eat()  # 继承父类方法,输出:旺财正在吃东西
dog.bark()  # 子类自有方法,输出:旺财正在汪汪叫

作业:

题目1

题目2:

题目3:

复制代码
import math

# 复用之前定义的 Circle 类和 Rectangle 类
class Circle:
    def __init__(self, radius=1):
        self.radius = radius

    def calculate_area(self):
        return math.pi * self.radius **2

    def calculate_circumference(self):
        return 2 * math.pi * self.radius

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

    def calculate_area(self):
        return self.length * self.width

    def calculate_perimeter(self):
        return 2 * (self.length + self.width)

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

# 图形工厂函数
def create_shape(shape_type, *args):
    """
    根据图形类型创建对应的图形对象
    :param shape_type: 图形类型,"circle" 或 "rectangle"
    :param *args: 图形参数(圆:半径;长方形:长、宽)
    :return: 对应的图形对象
    """
    if shape_type == "circle":
        # 圆需要 1 个参数(半径),若未传参则使用默认值 1
        radius = args[0] if args else 1
        return Circle(radius)
    elif shape_type == "rectangle":
        # 长方形需要 2 个参数(长、宽),若参数不足则用默认值 1 补充
        length = args[0] if len(args) >= 1 else 1
        width = args[1] if len(args) >= 2 else 1
        return Rectangle(length, width)
    else:
        # 不支持的图形类型
        raise ValueError(f"不支持的图形类型:{shape_type},支持的类型为 'circle' 和 'rectangle'")

# 测试工厂函数
if __name__ == "__main__":
    # 创建圆(半径为5)
    circle = create_shape("circle", 5)
    print(f"圆的面积:{circle.calculate_area():.2f},周长:{circle.calculate_circumference():.2f}")

    # 创建长方形(长10,宽4)
    rect = create_shape("rectangle", 10, 4)
    print(f"长方形的面积:{rect.calculate_area()},周长:{rect.calculate_perimeter()}")

    # 创建默认圆(未传参数,半径为1)
    default_circle = create_shape("circle")
    print(f"默认圆的面积:{default_circle.calculate_area():.2f}")

    # 创建正方形(长和宽均为6)
    square = create_shape("rectangle", 6, 6)
    print(f"正方形判断:{square.is_square()},面积:{square.calculate_area()}")

    # 测试不支持的图形类型(应报错)
    try:
        create_shape("triangle", 3, 4, 5)
    except ValueError as e:
        print(e)
相关推荐
AndreasEmil2 小时前
JavaSE - 继承
java·开发语言·ide·vscode·intellij-idea·idea
reasonsummer2 小时前
【教学类-89-11】20251209新年篇07——灰色姓名对联(名字做对联,姓氏做横批,福字贴(通义万相AI福字空心字))
python·通义万相
老华带你飞8 小时前
博物馆展览门户|基于Java博物馆展览门户系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·后端
liulilittle8 小时前
FileStream C++
开发语言·c++·cocoa
点PY9 小时前
C++ 中 std::async 和 std::future 的并发性
java·开发语言·c++
不会代码的小猴9 小时前
C++的第九天笔记
开发语言·c++·笔记
测试19989 小时前
功能测试、自动化测试、性能测试的区别
自动化测试·python·功能测试·测试工具·职场和发展·性能测试·安全性测试
CoderYanger9 小时前
Java SE——12.异常(≠错误)《干货笔记》
java·开发语言
Data_agent9 小时前
1688获得1688店铺所有商品API,python请求示例
java·开发语言·python