当前位置:首页>python>Python 类与函数:面向对象编程入门第一课

Python 类与函数:面向对象编程入门第一课

  • 2026-10-11 08:21:52
Python 类与函数:面向对象编程入门第一课

一种全新的思维方式|《Think Python》第14章

14. 类和函数

到目前为止,你已经知道如何使用函数组织代码,如何使用内置类型组织数据。下一步是学习面向对象编程,它使用自定义类型同时管理代码与数据。

本章我们从最简单的自定义类开始,学习定义类、创建对象、属性、纯函数、对象复制与时间计算,为面向对象编程打下基础。


14.1 自定义类型

我们可以定义新的类型,例如定义一个表示时间的类 Time。

自定义类型也叫作类(class)。

# 定义 Time 类,表示一天中的时间classTime:"""代表一天中的时间"""

定义类会创建一个类对象,它像一个工厂,用来生产具体的对象。

# 创建 Time 对象(实例化)lunch = Time()# 查看对象类型type(lunch)

运行结果:

__main__.Time
# 打印对象(显示类型和内存地址)print(lunch)

运行结果:

<__main__.Time object at 0x7f31440ad0c0>

创建对象的过程叫作实例化,这个对象就是 Time 类的一个实例。


14.2 属性

对象可以包含变量,这些变量叫作属性(attribute)。

我们用点号给对象添加属性:

# 给 lunch 对象添加时分秒属性lunch.hour = 11lunch.minute = 59lunch.second = 1

读取属性也用点号:

lunch.hour

运行结果:

11

格式化打印时间

# 打印 Time 对象,格式化为 00:00:00defprint_time(time):    s = f'{time.hour:02d}:{time.minute:02d}:{time.second:02d}'print(s)
# 调用打印print_time(lunch)

运行结果:

11:59:01

14.3 函数返回对象

函数可以创建并返回对象。

# 创建并返回一个 Time 对象defmake_time(hour, minute, second):    time = Time()    time.hour = hour    time.minute = minute    time.second = secondreturn time
# 使用工厂函数创建时间start = make_time(9, 20, 0)print_time(start)

运行结果:

09:20:00

14.4 对象是可变的

可以直接修改对象的属性。

# 给时间增加时长(直接修改原对象)defincrement_time(time, hours, minutes, seconds):    time.hour += hours    time.minute += minutes    time.second += seconds
# 测试:电影开始时间 + 时长start = make_time(9, 20, 0)increment_time(start, 1, 32, 0)print_time(start)

运行结果:

10:52:00

问题:这种方式会修改原对象。


14.5 对象复制

使用 copy 模块复制对象,不修改原数据。

from copy import copy# 复制一个对象start = make_time(9, 20, 0)end = copy(start)
# 两个对象内容相同print_time(start)print_time(end)

运行结果:

09:20:0009:20:00
# 但不是同一个对象start is end

运行结果:

False

注意:自定义对象默认 == 比较的是身份,不是内容。


14.6 纯函数

纯函数:不修改传入的对象,只返回新对象。

# 纯函数:时间相加,返回新对象,不修改原对象defadd_time(time, hours, minutes, seconds):# 复制原时间    total = copy(time)# 增加时间    increment_time(total, hours, minutes, seconds)# 返回新时间return total
start = make_time(9, 20, 0)end = add_time(start, 1, 32, 0)print_time(start)print_time(end)

运行结果:

09:20:0010:52:00

纯函数优点:

  • 不会意外修改数据
  • 更容易调试
  • 更安全

14.7 原型与修补(先跑再改)

先写出简单版本,再逐步修补边界问题。

原始 increment_time 没有处理满60进1:

start = make_time(9, 40, 0)end = add_time(start, 1, 32, 0)print_time(end)

运行结果:

10:72:00

改进版(处理进位)

defincrement_time(time, hours, minutes, seconds):# 先直接相加    time.hour += hours    time.minute += minutes    time.second += seconds# 秒进位到分    carry, time.second = divmod(time.second, 60)# 分进位到时    carry, time.minute = divmod(time.minute + carry, 60)# 时进位(24小时制)    carry, time.hour = divmod(time.hour + carry, 24)

现在结果正确:

start = make_time(9, 40, 0)end = add_time(start, 1, 32, 0)print_time(end)

运行结果:

11:12:00

14.8 先设计再开发(更优思路)

把时间看成 60进制数字,先转成秒,运算后再转回来。

# 时间 → 总秒数deftime_to_int(time):    minutes = time.hour * 60 + time.minute    seconds = minutes * 60 + time.secondreturn seconds
# 总秒数 → 时间defint_to_time(seconds):    minute, second = divmod(seconds, 60)    hour, minute = divmod(minute, 60)return make_time(hour, minute, second)

超级简洁的时间相加

defadd_time(time, hours, minutes, seconds):# 时长转为 Time 对象    duration = make_time(hours, minutes, seconds)# 都转为秒相加    seconds_total = time_to_int(time) + time_to_int(duration)# 转回时间return int_to_time(seconds_total)
start = make_time(9, 40, 0)end = add_time(start, 0, 90, 120)print_time(end)

运行结果:

11:12:00

优点:

  • 代码更短
  • 不易出错
  • 更容易扩展

14.9 调试工具

Python 提供了调试对象的工具:

# 查看类型type(start)

运行结果:

__main__.Time
# 判断是否为某个类的实例isinstance(start, Time)

运行结果:

True
# 判断是否有某个属性hasattr(start, 'hour')

运行结果:

True
# 将对象属性转为字典查看vars(start)

运行结果:

{'hour': 9, 'minute': 40, 'second': 0}

14.10 术语表

英文
中文
解释
object-oriented programming
面向对象编程
用对象组织代码与数据
class
类
自定义类型
class object
类对象
创建实例的工厂
instantiation
实例化
创建对象的过程
instance
实例
类创建出来的对象
attribute
属性
对象里的变量
pure function
纯函数
不修改参数,只返回新值
functional style
函数式风格
尽量使用纯函数
prototype and patch
原型修补
先跑通再逐步修正
design-first
先设计后开发
先想清楚再写代码

14.11 练习(带标准答案)

14.11.2 时间相减(求间隔秒数)

defsubtract_time(t1, t2):"""返回两个时间的间隔秒数"""return time_to_int(t1) - time_to_int(t2)

14.11.3 判断时间先后

defis_after(t1, t2):"""判断 t1 是否在 t2 之后"""return time_to_int(t1) > time_to_int(t2)

14.11.4 日期类练习

# 定义日期类classDate:"""代表年月日"""
# 创建日期对象defmake_date(year, month, day):    d = Date()    d.year = year    d.month = month    d.day = dayreturn d
# 格式化打印日期defprint_date(date):print(f'{date.year:04d}-{date.month:02d}-{date.day:02d}')
# 判断日期先后defis_after_date(d1, d2):return (d1.year, d1.month, d1.day) > (d2.year, d2.month, d2.day)

最新文章

随机文章