DAY 28 类的定义和方法-2025.9.15
类的定义和方法
知识点回顾:
- 类的定义
- pass占位语句
- 类的初始化方法
- 类的普通方法
- 类的继承:属性的继承、方法的继承
作业
题目1:定义圆(Circle)类
要求:
- 包含属性:半径 radius。
- 包含方法:
- calculate_area():计算圆的面积(公式:πr²)。
- calculate_circumference():计算圆的周长(公式:2πr)。
- 初始化时需传入半径,默认值为 1。
# 示例运行
circle = Circle(5)
print(f"半径:{circle.radius}") # 输出:半径:5
print(f"面积:{circle.calculate_area()}") # 输出:面积:78.54(保留两位小数)
print(f"周长:{circle.calculate_circumference()}") # 输出:周长:31.42(保留两位小数)
题目2:定义长方形(Rectangle)类
- 包含属性:长 length、宽 width。
- 包含方法:
- calculate_area():计算面积(公式:长×宽)。
- calculate_perimeter():计算周长(公式:2×(长+宽))。 is_square() 方法,判断是否为正方形(长 == 宽)。
- 初始化时需传入长和宽,默认值均为 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()}") # 输出:是否为正方形:Falsesquare = 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.42shape2 = create_shape("rectangle", 3, 4)
print(shape2.is_square()) # 输出:False
笔记:
在面向对象编程中,“类” 是描述具有相同属性和行为的对象的模板。比如 “人类” 可以看作一个类,包含 “姓名、年龄” 等属性,以及 “说话、走路” 等行为。下面逐一讲解类的核心概念:
1. 类的定义:创建对象的 “模板”
类通过class
关键字定义,语法如下:
class 类名:# 类的属性(数据)和方法(函数)
示例:定义一个描述 “人” 的类
class Person:# 类的属性和方法将在这里定义pass # 暂时用pass占位,后面会补充内容
- 类名通常使用 “驼峰命名法”(首字母大写,如
Person
、Student
),区分于函数的小写加下划线命名。 - 类是 “模板”,本身不占用内存;基于类创建的 “对象”(实例)才是具体的个体,比如
Person
类可以创建Alice
、Bob
等对象。
2. pass 占位语句:“先占个位置”
pass是 Python 中的空语句,用于 “语法上需要代码块但暂时没有具体实现” 的场景(比如类、函数、条件判断中),作用是避免语法错误。
示例:
class EmptyClass:pass # 这个类暂时没有任何内容,但定义是合法的def empty_func():pass # 这个函数暂时没有实现,不会报错
在类的定义中,当我们还没想好具体属性和方法时,用pass可以先完成类的框架搭建。
3. 类的初始化方法:创建对象时 “初始化属性”
初始化方法是类中特殊的方法,名为__init__
(前后各两个下划线),作用是在创建对象时自动执行,为对象初始化属性。
基本语法:
class 类名:def __init__(self, 参数1, 参数2, ...):# 初始化属性:self.属性名 = 参数self.属性1 = 参数1self.属性2 = 参数2
self
是必须的第一个参数,代表 “当前创建的对象本身”(类似 “我自己”),通过self.
属性名可以给对象绑定属性。- 创建对象时,传递的参数会自动传给
__init__
方法(无需手动传self
)。
示例:给Person
类添加初始化方法,绑定 “姓名” 和 “年龄” 属性
class Person:# 初始化方法:创建对象时自动调用,初始化name和age属性def __init__(self, name, age):self.name = name # 给对象绑定name属性self.age = age # 给对象绑定age属性# 基于Person类创建对象(实例)
alice = Person("Alice", 30) # 传递参数给__init__,self自动绑定到alice
bob = Person("Bob", 25)# 访问对象的属性
print(alice.name) # 输出:Alice
print(bob.age) # 输出:25
创建alice
对象时,__init__
自动执行,将"Alice"
赋值给alice.name
,30
赋值给alice.age
。
4. 类的普通方法:对象的 “行为”
普通方法是定义在类中的函数,用于描述对象的行为(比如 “说话”“计算” 等)。普通方法必须包含self
作为第一个参数,通过self
可以访问对象的属性或其他方法。
基本语法:
class 类名:def 方法名(self, 参数1, ...):# 方法逻辑(可以通过self访问属性)...
示例:给Person
类添加greet
(打招呼)和get_birth_year
(计算出生年份)方法
class Person:def __init__(self, name, age):self.name = nameself.age = age# 普通方法:打招呼def greet(self):# 通过self访问name属性return f"Hello, I'm {self.name}!"# 普通方法:计算出生年份def get_birth_year(self):return 2025 - self.age# 创建对象并调用方法
alice = Person("Alice", 30)
print(alice.greet()) # 输出:Hello, I'm Alice!
print(alice.get_birth_year()) # 输出:1995(2025-30)
- 调用方法时,无需传递
self
参数(Python 会自动将对象本身传给self
)。 - 方法中可以通过
self.属性名
访问对象的属性,也可以通过self.其他方法名()
调用类中的其他方法。
5. 类的继承:“子承父业” 减少重复代码
继承是面向对象的核心特性之一,允许子类(派生类)继承父类(基类)的属性和方法,从而减少代码重复。子类可以在父类基础上添加新属性 / 方法,或修改父类的方法(称为 “重写”)。
(1)基本语法:定义子类继承父类
class 父类名:# 父类的属性和方法class 子类名(父类名): # 括号中指定父类# 子类可以添加新属性/方法,或重写父类方法
(2)属性的继承
子类会自动继承父类的属性,但若子类有自己的__init__
方法,需要通过super()
手动调用父类的__init__
,否则父类的属性不会被初始化。
示例:Student
类继承Person
类,新增 “学号” 属性
class Person: # 父类def __init__(self, name, age):self.name = nameself.age = ageclass Student(Person): # 子类继承Persondef __init__(self, name, age, student_id):# 调用父类的__init__方法,继承name和age属性super().__init__(name, age) # super()代表父类# 新增子类自己的属性self.student_id = student_id# 创建Student对象
stu = Student("Charlie", 20, "2025001")# 访问继承的属性(来自Person)
print(stu.name) # 输出:Charlie
print(stu.age) # 输出:20# 访问子类新增的属性
print(stu.student_id) # 输出:2025001
super().__init__(name, age)
确保父类的name
和age
属性被正确初始化,否则子类对象会缺少这些属性。
(3)方法的继承与重写
子类会自动继承父类的方法,也可以重写父类的方法(定义与父类同名的方法),实现子类特有的逻辑。
示例:Student
类继承Person
的greet
方法,并新增study
方法,同时重写get_birth_year
方法
class Person:def __init__(self, name, age):self.name = nameself.age = agedef greet(self):return f"Hello, I'm {self.name}!"def get_birth_year(self):return 2025 - self.age # 父类的实现class Student(Person):def __init__(self, name, age, student_id):super().__init__(name, age)self.student_id = student_id# 新增子类自己的方法def study(self, course):return f"{self.name} is studying {course}."# 重写父类的get_birth_year方法(假设学生年龄计算方式不同)def get_birth_year(self):# 子类特有的逻辑:比实际年龄小1岁(举例)return 2025 - (self.age - 1)# 测试继承和重写
stu = Student("Charlie", 20, "2025001")# 继承父类的greet方法
print(stu.greet()) # 输出:Hello, I'm Charlie!# 调用子类新增的study方法
print(stu.study("Math")) # 输出:Charlie is studying Math.# 调用重写后的get_birth_year(使用子类逻辑)
print(stu.get_birth_year()) # 输出:2006(2025 - (20-1) = 2025-19=2006)# 父类的方法不受影响
person = Person("David", 40)
print(person.get_birth_year()) # 输出:1983(父类原逻辑)
- 继承:
Student
自动获得Person
的greet
方法,无需重新定义。 - 重写:
Student
的get_birth_year
与父类同名,调用时会执行子类的逻辑,实现了 “子类特有的行为”。
总结
- ** 类的定义 :用
class
关键字创建,是对象的模板。 - pass 语句 :临时占位,避免语法错误。
- 初始化方法
__init__
:创建对象时自动执行,用于初始化属性,必须包含self
。 - 普通方法 :描述对象的行为,第一个参数为
self
,可访问对象属性。 - 继承 **:子类通过
class 子类(父类)
继承父类的属性和方法:
- 属性继承:需用
super().__init__
调用父类初始化方法。 - 方法继承与重写:子类可直接使用父类方法,或重写方法实现自定义逻辑。
类和继承是面向对象编程的核心,能大幅提高代码的复用性和可维护性,在机器学习中(如定义模型类、数据处理类)应用广泛。
作业
题目1:定义圆(Circle)类
要求:
- 包含属性:半径 radius。
- 包含方法:
- calculate_area():计算圆的面积(公式:πr²)。
- calculate_circumference():计算圆的周长(公式:2πr)。
- 初始化时需传入半径,默认值为 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 = radiusdef calculate_area(self): ## 方法1 : 计算圆的面积area = math.pi * self.radius ** 2return areadef calculate_circumference(self): ## 方法2 :计算圆的周长circumference = 2 * math.pi * self.radiusreturn circumferencecircle = Circle(5)
print(f"半径:{circle.radius}")
print(f"面积:{circle.calculate_area():.2f}")
print(f"周长:{circle.calculate_circumference():.2f}")
半径:5
面积:78.54
周长:31.42
题目2:定义长方形(Rectangle)类
- 包含属性:长 length、宽 width。
- 包含方法:
- calculate_area():计算面积(公式:长×宽)。
- calculate_perimeter():计算周长(公式:2×(长+宽))。
- is_square() 方法,判断是否为正方形(长 == 宽)。
- 初始化时需传入长和宽,默认值均为 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()}") # 输出:是否为正方形:Falsesquare = Rectangle(5, 5)
print(f"是否为正方形:{square.is_square()}") # 输出:是否为正方形:True
解答
class Rectangle: ## 定义类def __init__(self, length=1, width=1): ## 初始化属性self.length = lengthself.width = widthdef calculate_area(self): ## 方法1 : 计算面积area = self.length * self.widthreturn areadef calculate_perimeter(self): ## 方法2 : 计算周长perimeter = 2 * (self.length + self.width)return perimeterdef is_square(self): ## 方法3 : 判断是否为正方形if self.length == self.width:return Trueelse:return Falserect = Rectangle(4, 6)
print(f"长:{rect.length}, 宽:{rect.width}")
print(f"面积:{rect.calculate_area()}")
print(f"周长:{rect.calculate_perimeter()}")
print(f"是否为正方形:{rect.is_square()}") square = Rectangle(5, 5)
print(f"是否为正方形:{square.is_square()}") r = Rectangle()
print(f"长:{r.length}, 宽:{r.width}")
print(f"面积:{r.calculate_area()}")
print(f"周长:{r.calculate_perimeter()}")
print(f"是否为正方形:{r.is_square()}")
长:4, 宽:6
面积:24
周长:20
是否为正方形:False
是否为正方形:True
长:1, 宽:1
面积:1
周长:4
是否为正方形:True
题目3:图形工厂
创建一个工厂函数 create_shape(shape_type, *args),
根据类型创建不同图形对象:图形工厂(函数或类)
shape_type=“circle”:创建圆(参数:半径)。
shape_type=“rectangle”:创建长方形(参数:长、宽)。
shape1 = create_shape("circle", 5)
print(shape1.calculate_circumference()) # 输出:31.42shape2 = create_shape("rectangle", 3, 4)
print(shape2.is_square()) # 输出:False
解答
def create_shape(shape_type, *args):"""根据类型和参数创建图形对象参数:shape_type: 图形类型,"circle"表示圆,"rectangle"表示长方形*args: 图形参数,圆需要1个参数(半径),长方形需要2个参数(长、宽)返回:对应的图形对象,如果类型或参数无效则返回None"""try:if shape_type == "circle":# 检查圆的参数数量if len(args) > 1:raise ValueError("创建圆只需要1个半径参数")# 若未提供参数,使用默认值1radius = args[0] if args else 1return Circle(radius)elif shape_type == "rectangle":# 检查长方形的参数数量if len(args) > 2:raise ValueError("创建长方形只需要2个参数(长、宽)")# 若未提供或只提供部分参数,使用默认值1length = args[0] if len(args) >= 1 else 1width = args[1] if len(args) >= 2 else 1return Rectangle(length, width)else:raise ValueError(f"不支持的图形类型: {shape_type},仅支持'circle'和'rectangle'")except ValueError as e:print(f"创建图形失败: {e}")return Noneshape1 = create_shape("circle", 5)
print(f'{shape1.calculate_circumference():.2f}') shape2 = create_shape("rectangle", 3, 4)
print(shape2.is_square())
31.42
False
@浙大疏锦行