Skip to content

Python编程3种范式: 面向过程 vs. 函数式编程 vs. 面向对象

内容简介

在上一节课,我们学了Python的基本语法,了解了Python的基本数据类型和运算符,掌握了Python的基本输入输出方法——而这些语法结构有哪些?你还有印象么?

课堂回顾

  1. 变量、数据类型及其数学操作
  2. 程序输出的格式化打印
  3. 逻辑运算符支撑起来的条件语句
  4. 循环语句的使用

这些基本的语法结构,基本上在所有的现代编程语言都有所体现。可以这么说,如果掌握了这些语法应用的精髓,你已经学会了绝大部分编程语言的初级使用方法。

而近现代编程语言的一大进步,就是引入了“面向过程”或“面向对象”的编程思想。面向过程的编程思想,强调的是“过程”,即一系列的操作步骤;而面向对象的编程思想,强调的是“对象”,即数据和操作数据的方法。

而最能体现这两种编程思想的,就是“函数”和“类->对象”了。函数是面向过程的编程思想的体现,而类是面向对象的编程思想的体现。 在本节课,我们将通过上机编程,掌握Python中面向过程和面向对象的编程思想的基本应用。

Pick up some knowledge about FUNCTIONAL PROGRAMMING paradigm

面向过程的编程范式,在近5年间已经有向“函数式编程”转变的趋势。函数式编程强调的是“函数”,即一系列的操作步骤;而面向对象的编程思想,强调的是“对象”, 即数据和操作数据的方法。

感兴趣的同学可以通过我们的课堂AI助手自行学习了解,导学问题:

  • 什么是函数式编程?
  • 函数式编程的特点是什么?
  • 函数式编程和基于函数的面向过程编程有什么区别?

范式1: Python函数及面向过程编程

函数(function)是Python中最基本的编程单元,是一个可以被调用的代码块,它可以接收输入参数,并返回一个输出结果。函数可以用来封装一段代码, 以便在需要时重复使用。函数的定义格式如下:

python
def function_name(parameters):
    # code block
    return result

举个栗子。比较两个数,并返回较大的数:

python
def max(a, b):
    if a > b:
        return a
    else:
        return b

在上面的代码中,我们定义了一个函数max,它接收两个参数a和b,并返回较大的数。我们可以通过调用这个函数来比较两个数:

python
print(max(1, 2)) # 输出 2
print(max(3, 2)) # 输出 3

函数的参数可以是任意类型的数据,包括数字、字符串、列表、字典等。函数的返回值也可以是任意类型的数据,包括数字、字符串、列表、字典等。

本节任务:

  1. 边读边练资料Python3 函数
  2. 借助课堂AI助手或其它资料,研究如下问题de代码实现:
    1. [必选] 函数的参数可以是任意类型的数据,包括数字、字符串、列表、字典等。
    2. [必选] 函数的返回值也可以是任意类型的数据,包括数字、字符串、列表、字典等。
    3. [必选] 函数的参数可以是匿名函数,也可以是命名函数。
    4. [必选] 函数的参数可以有默认值,也可以有可变参数。
    5. 函数的参数可以是关键字参数,也可以是位置参数。
    6. 函数的参数可以是可变参数,也可以是不可变参数。

为什么说函数的调用体现了Python“面向过程编程”范式?

因为函数的调用是一个过程,它是一个有序的步骤。我们可以把函数看作一个黑箱,我们只需要知道它的输入和输出,而不需要关心它的内部实现细节。 这就是“面向过程编程”的思想:我们只需要关心“做什么”,而不需要关心“怎么做”。 举个栗子:

python
def add(a, b):
    return a + b
def subtract(a, b):
    return a - b
def multiply(a, b):
    return a * b
def divide(a, b):
    return a / b
def calculator(a, b, operation):
    if operation == '+':
        return add(a, b)
    elif operation == '-':
        return subtract(a, b)
    elif operation == '*':
        return multiply(a, b)
    elif operation == '/':
        return divide(a, b)
    else:
        raise ValueError("Invalid operation")

在上面的代码中,我们定义了一个计算器函数calculator,它接收两个数字和一个操作符,并根据操作符调用相应的函数来进行计算。如下面的代码所示:

python
print(calculator(1, 2, '+')) # 输出 3
print(calculator(1, 2, '-')) # 输出 -1
print(calculator(1, 2, '*')) # 输出 2
print(calculator(1, 2, '/')) # 输出 0.5

我们在REPL中可以直接调用这个函数,而程序按照预定义的“步骤”执行,这就是“过程”。我们只需要关心调用相关函数去“做什么”, 而不需要关心被调用函数的内部是“怎么做”的。

范式2: Python的函数式编程

导学提示



在Python中,函数式编程是一种编程范式,它强调使用函数来处理数据,而不是使用对象和类。函数式编程的核心思想是将计算视为数学函数的求值,而不是状态的变化。

“高阶函数”最能体现函数式编程思想了。高阶函数是指可以接收函数作为参数或返回一个函数的函数,Python中最常用的有map,filter,reduce等。

我们以高阶函数之一的filter为例。filter函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器。举个栗子:

Python
def is_even(n):
    return n % 2 == 0
def is_odd(n):
    return n % 2 != 0
def is_positive(n):
    return n > 0
def is_negative(n):
    return n < 0
def is_zero(n):
    return n == 0

调用fiter中调用上述自定义函数is_even(),过滤得到偶数:

python
numbers = [1, 2, 3, 4, 5, -1, -2, -3, -4, -5]
filtered_numbers = filter(is_even, numbers)
print(list(filtered_numbers)) # 输出 [2, 4, -2, -4]

本节任务:

  1. 阅读filter,学习filter函数的用法。
  2. 利用filter和上述我们自定义的is_odd()is_positive()is_negative()is_zero()函数,过滤得到奇数、正数、负数和零。
  3. 阅读map/reduce,学习map函数的用法。
  4. 自学lambda表达式(匿名函数),体会lambda函数的简洁性,感受它与filter, map之间微妙的关系。

范式3: Python类及面向对象编程

面向对象编程是一种编程范式,它强调使用对象来处理数据,而不是使用函数。面向对象编程的核心思想是将数据和操作数据的方法封装在一起,形成一个对象。

对象(也有人称为“实例”)是类的实例,类是对象的模板。类定义了对象的属性和方法,而对象则是类的具体实现。 类的定义格式如下:

python
class ClassName:
    def __init__(self, parameters):
        # 构造函数
        self.attribute = parameters

    def method(self):
        # 方法
        pass

代码解释:

  1. 类的构造函数__init__用于初始化对象的属性,方法用于定义对象的行为。我们可以通过创建类的实例来使用类。
  2. 类的属性self.attribute 可以是任意类型的数据,包括数字、字符串、列表、字典等。注意关键字self
  3. 类的方法其实就是定义在类中的函数,它可以访问类的属性和其他方法。方法的第一个参数必须是self,表示对象本身。

关于Python类的定义最需要关注的知识点有(按照重要性降序排列):

  1. 类的构造函数__init__:用于初始化对象的属性。
  2. 类的方法:用于定义对象的行为。
  3. 类的属性:用于存储对象的数据。
  4. 类的继承:用于实现代码的重用。

本节任务:

  1. 阅读Python3 面向对象,学习Python的类的定义方法;
  2. 实践任务:根据课堂AI助手的提示,定义一个类,并实现如下功能:
    1. 定义一个类,包含一个属性和一个方法。类的名字为Person,属性为name,方法为say_hello()
    2. __init__()方法中初始化属性name
    3. say_hello()方法中打印"Hello, my name is {name}"
    4. 创建一个Person类的实例,并调用say_hello()方法。
    5. 在定义一个继承自Person类的子类Student,并重写say_hello()方法,打印"Hello, my name is {name}, I am a student"
    6. 创建一个Student类的实例,并调用say_hello()方法。
  3. if any time available, 开始着手本章最后的课程设计作业。
  4. 拓展:阅读获取对象信息,学习如何获取对象的信息。

本章小节

  • 本章我们学习了Python的函数、类和面向对象编程的基本概念。
  • 我们通过上机编程,掌握了Python中函数和类的基本应用。
  • 我们还学习了Python中函数式编程的基本概念和应用。

课程设计作业

简介

课程设计作业是大学教学中一种常见的实践性学习任务,通常是在某一门课程结束时或学期末布置的综合性项目。它的目的是帮助学生将所学的理论知识应用到实际问题中,培养分析、解决复杂问题的能力,并提升实践技能。

课程设计作业

本次作业是Python编程实践的课程设计作业,要求利用Python的类和对象的语法,实现如下功能:

  1. 定义一个长方体的类Cuboid,包含属性lengthwidthheight
  2. 在类Cuboid中定义一个构造函数__init__(),初始化lengthwidthheight
  3. 在类Cuboid中定义一个方法volume(),计算长方体的体积;
  4. 在类Cuboid中定义一个方法surface_area(),计算长方体的表面积;
  5. 创建一个立方体的类Cube继承Cuboid类,重写__init__()方法,初始化lengthwidthheight为相等的值;
  6. 计算立方体的体积和表面积,调用volume()surface_area()方法;
  7. Cube类中定义一个方法diagonal(),计算立方体的对角线长度;
  8. 分别创建CuboidCube类的实例,调用它们的方法,输出结果。
  9. 比较CuboidCube实例的体积和表面积,输出结果。
  10. 假如我们在设计CuboidCube类时,还要考虑它们的材质,譬如铜、铁、铝、金的密度,请修增加各自的类的方法,以计算其:
    • 体积
    • 表面积
    • 重量
    • 费用成本

Python编程实践课程设计作业的出现也意味着我们即将告一段落,所以本次作业大家可以慢慢地、细致地完成。我们会在下节课上进行答疑和讨论,然后告知 家如何利用手中的Python技能融入社会中更大的生态。