python基础-面向对象编程-练习

通过习题对比面向过程与面向对象编程,展示类、对象、类属性、实例方法、类方法及静态方法的定义与使用。涵盖列表偶数和计算、书籍与汽车类设计、学生信息管理、圆面积计算及日志记录等Python实现。

Posted by Hilda on July 3, 2025

面向对象编程习题

(1)两大编程思想

习题 1.1 (面向过程)

编写一个面向过程的程序,计算并打印一个列表中所有偶数的和。

○ 定义一个列表 numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

○ 定义一个函数 sum_even_numbers(num_list),接收列表作为参数,计算偶数和并返回。

○ 调用函数并打印结果。


参考:

1
2
3
4
5
6
7
8
9
10
# 计算并打印一个列表中所有偶数的和
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def sum_even_numbers(num_list):
    sum = 0
    for n in num_list:
        if n % 2 == 0:
            sum += n
    return sum
res1 = sum_even_numbers(numbers)
print(f"{numbers}中所有偶数的和是:{res1}")

image-20250703111240971

习题 1.2 (面向对象)

将习题1.1中的功能改写为面向对象的方式。

○ 定义一个 NumberProcessor 类。

○ 在 init 方法中接收一个数字列表作为实例属性。

○ 定义一个 sum_even_numbers 方法,该方法不接收额外参数,而是使用实例属性中的列表来计算偶数和并返回。

○ 创建 NumberProcessor 对象,并调用其方法。


参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class NumberProcessor:
    def __init__(self, num_list):
        self.num_list = num_list
        print(f"对象已创建,初始数字列表是:{self.num_list}")

    def sum_even_numbers(self):
        sum = 0
        for n in self.num_list:
            if n % 2 == 0:
                sum += n
        return sum

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
np = NumberProcessor(numbers)
res2 = np.sum_even_numbers()
print(f"{np.num_list}中所有偶数的和是:{res2}")

image-20250703111728411

(2)类和对象的创建

习题 2.1

创建一个 Book 类,包含 title (书名) 和 author (作者) 两个实例属性。

○ 在 init 方法中初始化这两个属性。

○ 添加一个 display_info 方法,打印书名和作者信息。

○ 创建两个 Book 对象,并调用它们的 display_info 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author
        print(f"由{self.author}写的《{self.title}》书被创建了")

    def display_info(self):
        print(f"信息:由{self.author}写的《{self.title}》书")

book1 = Book("计算机网络", "James F. Kurose, Keith W. Ross")
book2 = Book("TCP/IP 详解", "W. Richard Stevens")
book1.display_info()
book2.display_info()

image-20250703113822622

习题 2.2

创建一个 Car 类,包含 make (品牌), model (型号) 和 year (年份) 三个实例属性。

○ 在 init 方法中初始化这些属性。

○ 添加一个 start_engine 方法,打印 "[make] [model] engine started."

○ 创建一个 Car 对象,并调用其 start_engine 方法。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Car:
    def __init__(self, make, model, year):
        '''
        make: 品牌
        model: 型号
        year: 年份
        '''
        self.make = make
        self.model = model
        self.year = year

    def start_engine(self):
        print(f"[{self.make}][{self.model}] 发动机启动了!")

car1 = Car("Honda", "Civic Sedan Sport Touring Hybrid", 2025)
car1.start_engine()

image-20250703114410875

(3)类对象和类属性

习题 3.1

创建一个 Student 类,包含以下属性:

○ 一个类属性 school_name,默认值为 “High School A”。

○ 一个类属性 student_count,用于记录创建了多少个学生实例。

○ 实例属性 name 和 age。

○ 在 init 方法中初始化实例属性,并确保 student_count 正确递增。

○ 添加一个 get_info 方法,打印学生的姓名、年龄和学校名称。

○ 创建两个 Student 对象,打印它们的 get_info,然后打印 Student.student_count


参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Student:
    school_name = "High School A"
    student_count = 0   # 记录创建了多少个学生实例
    def __init__(self, name, age):  # 实例属性 name 和 age
        self.name = name
        self.age = age
        Student.student_count += 1

    def get_info(self):
        # 打印学生的姓名、年龄和学校名称
        print(f"学生姓名:{self.name}, 学生年龄:{self.age}, 学校名称:{self.school_name}")

# 创建两个 Student 对象,打印它们的 `get_info`,然后打印 `Student.student_count`。
s1 = Student("Adele", 16)
print(f"Student.student_count:{Student.student_count}")
s2 = Student("Bob", 18)
print(f"Student.student_count:{Student.student_count}")
s1.get_info()
s2.get_info()

image-20250703142547565

习题 3.2

在习题3.1的基础上,演示类属性的“遮蔽”现象。

○ 创建一个新的 Student 实例 student3。

○ 通过 student3 实例修改其 school_name 为 “University B”。

○ 打印 student3.get_info()

○ 打印 Student.school_name 和之前创建的 student1.get_info(),观察它们是否受到影响。


1
2
3
4
student3.school_name = "University B"
student3.get_info()
print(f"Student.school_name:{Student.school_name}")
s1.get_info()

image-20250703142822573

(4)类方法与静态方法

习题 4.1

创建一个 Circle 类,包含以下内容:

○ 一个类属性 PI,值为 3.14159。

○ 一个实例属性 radius (半径)。

○ 一个实例方法 calculate_area,计算并返回圆的面积。

○ 一个类方法 from_diameter,接收直径作为参数,并返回一个 Circle 实例。

○ 一个静态方法 is_valid_radius,接收一个数字作为参数,判断它是否是有效的半径(大于0)。

○ 创建两个 Circle 对象:一个通过 init 创建,一个通过 from_diameter 创建。

○ 调用它们的 calculate_area 方法。

○ 使用 is_valid_radius 验证一些半径值。


参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Circle:
    # 类属性 PI,值为 3.14159。
    PI = 3.1415926
    # 实例属性 radius (半径)。
    def __init__(self, radius):
        self.radius = radius

    # 实例方法 calculate_area,计算并返回圆的面积。
    def calculate_area(self):
        return Circle.PI * self.radius * self.radius

    # 类方法 from_diameter,接收直径作为参数,并返回一个 Circle 实例。
    @classmethod
    def from_diameter(cls, diameter):
        return cls(diameter / 2)

    # 静态方法 is_valid_radius,接收一个数字作为参数,判断它是否是有效的半径(大于0)
    @staticmethod
    def is_valid_radius(arg):
        return arg > 0


c1 = Circle(3)
c2 = Circle.from_diameter(6)
print(f"c1的半径是:{c1.radius}, 面积是:{c1.calculate_area()}")
print(f"c2的半径是:{c2.radius}, 面积是:{c2.calculate_area()}")

print(Circle.is_valid_radius(9))
print(Circle.is_valid_radius(-1))

image-20250703161438697

习题 4.2

创建一个 Logger 类,用于记录日志。

○ 一个类属性 log_level,默认值为 “INFO”。

○ 一个类方法 set_log_level(cls, level),用于修改 log_level

○ 一个静态方法 format_message(message),接收一个字符串,返回格式化后的消息(例如,”[TIMESTAMP] - MESSAGE”)。

○ 一个实例方法 log(self, message),根据当前的 log_level 打印消息(例如,如果 log_level 是 “INFO”,则打印所有消息;如果是 “ERROR”,则只打印错误消息)。

○ 创建 Logger 实例,测试不同日志级别下的消息打印。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from datetime import datetime
class Logger:
    # 类属性 log_level,默认值为 "INFO"。
    log_level = "INFO"

    # 类方法 set_log_level(cls, level),用于修改 log_level。
    @classmethod
    def set_log_level(cls, level):
        Logger.log_level = level

    # 静态方法 format_message(message),接收一个字符串,返回格式化后的消息(例如,"[TIMESTAMP] - MESSAGE")。
    @staticmethod
    def format_message(message):
        formatted_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print(f"[{formatted_time}]-{message}")

    # 实例方法 `log(self, message)`,根据当前的 log_level 打印消息
    # (例如,如果` log_level `是 "INFO",则打印所有消息;如果是 "ERROR",则只打印错误消息)。
    def log(self, message):
        if Logger.log_level == "INFO":
            print(message)
        elif Logger.log_level == "ERROR":
            print(f"错误消息:{message}")

logger = Logger()
logger.format_message("设备状态良好")
logger.set_log_level("ERROR")
logger.log("设备需重启,回滚")
logger.format_message("设备已回滚")

image-20250703162441779