Python函数详解,函数式编程,模块化设计

一、函数

函数是一段具有特定功能的、可重用的语句组,通过函数名来表示和调用。

  • 函数是一段代码的抽象和封装
  • 函数是一段具有特定功能的、可重用的语句组
  • 函数是一种功能的抽象,表达特定功能
  • 两个作用:降低编程难度代码复用
    降低编程难度:利用函数可以将一个复杂的大问题分解成一系列简单的小问题,分而治之,为每个小问题编写程序,通过函数封装,当各个小问题都解决了,大问题也就迎刃而解。
    代码复用:函数可以在一个程序中的多个位置使用,也可以用于多个程序,当需要修改代码时,只需要在函数中修改一次,所有调用位置的功能都更新了,这种代码复用降低了代码行数和代码维护难度。

二、定义函数(声明函数)

Python函数详解,函数式编程,模块化设计_第1张图片
Python函数详解,函数式编程,模块化设计_第2张图片

  1. 函数名:def保留字,函数名可以是任何有效的Python标识符
  2. 参数列表:参数列表是调用该函数时传递给它的值
  • 参数可以有零个、一个、多个,当传递多个参数时各参数由逗号分隔,当没有参数时也要保留圆括号
  • 参数列表中的参数是形式参数,简称为“形参”,相当于实际参数的一种符号表示或占位符
  • 参数分为非可选参数、可选参数
  1. 函数体:函数体是函数每次被调用时执行的代码,由一行或多行语句组成
  2. return返回值:如果需要返回值,使用保留字return和返回值列表
  • 一个函数可以有零个、一个、多个return
  • 当有return时,可以有零个、一个、多个返回值
  • 当有return时,当返回多个值时,这些值形成一个元祖数据类型
# 定义一个对整数n求阶乘的函数
def fact(n):
    s = 1
    for i in range(1, n+1):
        s *= i
    return s

三、调用函数

函数定义后不能直接运行,需要调用才能运行,函数调用方式:
<函数名>(<实际赋值参数列表>)

  • 对函数的各个参数赋予实际值,实际值可以是实际数据,也可以是在调用函数前已经定义过的变量。
  • 函数返回:函数执行结束后,根据return保留字决定是否返回结果,如果返回结果,则结果将被放置到函数被调用的位置,函数调用就此完毕

Python函数详解,函数式编程,模块化设计_第3张图片

# 定义一个对整数n求阶乘的函数
def fact(n):
    s = 1
    for i in range(1, n+1):
        s *= i
    return s
print("值是:", fact(10))

输出:
值是: 3628800
  • 函数式编程;尽量把程序写成一系列函数调用,在编程中大量使用函数已成为一种编程范式,叫作函数式编程

1. 函数类型

  • 在Python中,函数也是有类型的,可以通过type()获得函数类型,
  • 函数类型为function类型,这是一种Python的内置类型
  • 如果调用函数,则类型为返回值的类型
    Python函数详解,函数式编程,模块化设计_第4张图片
    2. 最小函数
    Python语言最小函数可以不表达任何功能:
    Python函数详解,函数式编程,模块化设计_第5张图片
    保留字pass表示不进行任何操作,起到占位的作用。对f()的调用不实现任何功能。
    Python函数详解,函数式编程,模块化设计_第6张图片
    此处的16进制数0x000001DF7C674E58表示f()的内存地址,转换成十进制就是2059376479832。

四、函数参数:可选参数

Python函数详解,函数式编程,模块化设计_第7张图片
Python函数详解,函数式编程,模块化设计_第8张图片
可选参数要放置在必选参数的后面,即定义函数时,先给出所有非可选参数,然后再分别列出每个可选参数及对应的默认值。
Python函数详解,函数式编程,模块化设计_第9张图片
函数的参数在定义时可以指定默认值,当函数被调用时,如果没有传入对应的参数值,则使用函数定义时的默认值替代。

五、函数参数:可变参数

Python函数详解,函数式编程,模块化设计_第10张图片
确定要给的参数放在前面,不确定的参数放在后面

Python函数详解,函数式编程,模块化设计_第11张图片

def fact(n, *c):
    s = 1
    for i in range(1, n+1):
        s *= i
    for item in c:
        s *= item
    return s

print(fact(4))   输出:24
print(fact(4, 2))   输出:48
print(fact(4, 2, 5))   输出:240
print(fact(4, 2, 5, 3))   输出:720

max(), min()的参数就是可变参数,在函数定义时参数就是设定为不确定的 *b方式

六、函数参数:参数传递

  1. 按位置传递参数:默认按照位置顺序的方式传递参数
  2. 按参数名称传递参数,采用名称参数方式不需要保持参数传递的顺序,只需要对每个必要参数赋予实际值即可,这种方式会显著增强程序的可读性
    Python函数详解,函数式编程,模块化设计_第12张图片

七、函数返回值

  1. return返回值:如果需要返回值,使用保留字return和返回值列表
  • 一个函数可以有零个、一个、多个return
  • 当有return时,可以有零个、一个、多个返回值
  • 当有return时,当返回多个值时,中间用逗号分隔,这些值形成一个元祖数据类型
    Python函数详解,函数式编程,模块化设计_第13张图片
    Python函数详解,函数式编程,模块化设计_第14张图片
def add(x, y):
    z = x + y

print(add(2, 3))

输出:
None   # 没有return保留字,输出None
def add(x, y):
    z = x + y
    return

print(add(2, 3))

输出:
None   # 有return保留字,但没有列返回值,输出None

八、变量作用域:局部变量

  • 根据变量在程序中的位置和作用范围,变量分为局部变量和全局变量。
  • 局部变量仅在函数内部,且作用域也在函数内部;全局变量的作用域跨越多个函数。
  • 基本数据类型的变量,无论是否重名,局部变量与全局变量不同
  • 可以通过global保留字在函数内部声明全局变量
  • 组合数据类型的变量:如果局部变量未真实创建,则是全局变量
  1. 局部变量:局部变量指在函数内部定义的变量,仅在函数内部有效,当函数退出时变量不再存在。
def multiply(x, y = 10):
    z = x * y  # z是函数内部的局部变量
    return z

s = multiply(99, 2)
print(s)
print(z)

输出:
198
Traceback (most recent call last):
  File "C:/Users/520/PycharmProjects/pythonProject1/exercise.py", line 6, in <module>
    print(z)
NameError: name 'z' is not defined

九、变量作用域:全局变量

  1. 全局变量是在函数之外定义的变量,在程序执行全过程有效,全局变量在函数内部使用时,需要提前使用保留字global声明
    语法:global<全局变量>
    Python函数详解,函数式编程,模块化设计_第15张图片
n = 2  # n是全局变量
def multiply(x, y = 10):
    global n  # 声明全局变量n
    n = x * y # 声明全局变量n
    return x * y * n  # 使用全局变量n

s = multiply(5, 3)
print("s的值是:", s)
print("n的值是:", n)

输出:
s的值是: 225
n的值是: 15

如果未使用保留字global声明,即使名称相同,也不是全局变量,程序将其作为局部变量处理:

n = 2  # n是全局变量
def multiply(x, y = 10):
    n = x * y  # n变量名相同,没有声明为全局变量,直接使用,是局部变量
    return x * y * n

s = multiply(5, 3)
print("s的值是:", s)
print("n的值是:", n)

输出:
s的值是: 225
n的值是: 2  #不改变外部全局变量的值

Python函数详解,函数式编程,模块化设计_第16张图片
Python函数详解,函数式编程,模块化设计_第17张图片
Python函数详解,函数式编程,模块化设计_第18张图片

十、变量作用域:全局变量(组合数据类型)

Python函数详解,函数式编程,模块化设计_第19张图片

十一、lambda函数

匿名函数(lambda函数):lambda函数是一种快速定义单行的最小函数,是从Lisp借用来的,可以用在任何需要函数的地方。
Python函数详解,函数式编程,模块化设计_第20张图片
Python函数详解,函数式编程,模块化设计_第21张图片
lambda函数与def函数的区别:

  • lambda函数使用返回值作为函数名,不适用return保留字,它的表达式相当于def函数的函数体
f = lambda x, y: x + y  # 定义一个lambda函数f,进行加法运算
print(f(10, 15))

输出: 25

f = lambda: "lambda函数"  # lambda函数可以没有参数
print(f())

输出:lambda函数

Python函数详解,函数式编程,模块化设计_第22张图片

  • 一般在编写代码时,哪怕这个函数只有一行,也建议使用def和return这种方法来定义,要谨慎使用lambda函数。
  • lambda函数不是定义函数的常用形式,它的存在主要是用作一些特定的函数或方法的参数,有一些非常复杂的函数,它的某一个参数就是一个函数,这种情况下使用lambda函数。

小结:
Python函数详解,函数式编程,模块化设计_第23张图片

十二、代码复用和模块化设计

  • 可以把编写的代码当做一种资源,并且对这种资源进一步抽象,实现代码的抽象化。代码抽象化指的是使用函数等方法对代码赋予更高级别的定义。对同一份代码在需要时被重复使用就构成了代码复用,而代码复用是需要将代码进行抽象才能达到的效果。

  • 在不同的程序设计语言中,都有代码复用的相关功能。一般来说,我们使用函数和对象这两种方法来实现代码复用。可以认为这两种方法是实现代码复用的方法,也可以认为这两种方法是对代码进行抽象的不同级别。函数能够命名一段代码,在代码层面建立初步抽象,但这种抽象级别比较低,因为它只是将代码变成了一个功能组。对象通过属性和方法,能够将一组变量甚至一组函数进一步进行抽象。

  • 在代码复用的基础上,我们可以开展模块化设计。模块化设计是基于一种逻辑的设计思维,它的含义是通过封装函数或对象将程序划分为模块以及模块之间的表达。

– 紧耦合:尽可能合理划分功能块,功能块内部耦合紧密
– 松耦合:模块间关系尽可能简单,功能块之间耦合度低
– 紧耦合的缺点在于更新一个模块可能导致其他模块变化,复用较困难;松耦合一般基于消息或协议时间,系统间交互简单。
– 松耦合代表了模块化,从系统观点来看,松耦合是总体设计原则

  • 一般来说,完成特定功能或被经常复用的一组语句应该采用函数来封装,并尽可能减少函数间参数和返回值的数量。

  • 一般编写程序时,通过函数来将一段代码与代码的其他部分分开,那么函数的输入参数和返回值就是这段函数与其他代码之间的交流通道,这样的交流通道越少越清晰,那么定义的函数复用可能性就越高。所以在模块化设计过程中,对于模块内部,也就是函数内部,尽可能的紧耦合,它们之间通过局部变量可以进行大量的数据传输。但是在模块之间,也就是函数与函数之间要尽可能减少它们的传递参数和返回值,让它们之间以松耦合的形式进行组织,这样每一个函数才有可能被更多的函数调用,它的代码才能更多的被复用

PS. source, python123.io

你可能感兴趣的:(函数,python)