Python函数式编程

简介: Python函数式编程:函数的基本用法:定义、调用、参数、返回值,变量:局部变量、全局变量、获取指定作用域的变量,局部函数、nonlocal关键字,lambda表达式,递归,python高阶函数:map、filter、reduce

一、Python函数的定义

函数就是一段封装好的,可以重复使用的代码,它使得我们的程序更加模块化,不需要编写大量重复的代码。函数还可以接收参数,并根据参数的不同做出不同的操作,最后再把处理结果返回给我们。函数的本质就是一段有特定功能、可以重复使用的代码。

二、函数的调用

基本语法:

def functionname( parameters ):

"函数_文档字符串"

function_suite

return [expression]

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
  • 圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于说明函数用途。
  • 函数内容以冒号起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

函数调用的基本语法格式:

[返回值] = 函数名([形参值])

三、函数值传递和引用传递

在使用函数时,经常会用到形式参数(简称“形参”)和实际参数(简称“实参”),二者之间的区别是:

  • 形式参数:在定义函数时,函数名后面括号中的参数就是形式参数。
  • 实际参数:在调用函数时,函数名后面括号中的参数称为实际参数,也就是函数的调用者给函数的参数。

Python 函数的参数传递:

不可变类型:类似 C++ 的传值调用(实际上重新复制了一个副本给形参,不改变调用函数实参变量的内容),如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。

可变类型:类似 C++ 的引用传递(也叫传址调用:将实参地址给形参,将改变调用函数实参变量的内容),列表,字典。如 fun(a),则是将 a 真正的传过去,修改后fun外部的a也会受影响

四、函数中的参数用法

调用函数时常用的参数使用类型:

◆ 位置参数(必选参数):函数调用时,实参默认按位置顺序进行传递,并且要求个数和形参完全匹配。

◆ 默认参数:调用函数时,默认参数的值如果没有传入,则被认为是默认值。

◆ 命名参数 (关键字参数):使用关键字参数允许函数调用时参数的顺序与声明时不一致,通过参数名进行匹配。

◆ 可变参数:你可能需要一个函数能处理比当初声明时更多的参数,这些参数叫做不定长参数或可变参数。

# 函数中参数的用法# 位置参数deflocation_param(a, b, c):
print(a, b, c)
location_param(1, 2, 3)  # 1 2 3# 默认参数defdefault_param(a, b, c=20):  # 默认值要放在最后面print(a, b, c)
default_param(8, 9)  # 8,9,20  未传入默认值时,打印默认值default_param(8, 9, 10)  # 8,9,10  传入默认值时,实际传入的值会覆盖默认值# 命名参数default_param(b=5, a=9, c=10)  # 9 5 10  命名参数的顺序可以自定义# 可变参数-元组形式defvariable_param_1(a, *b):
print(a, b)
variable_param_1(1, 2, 3)  # 1 (2, 3)# 可变参数-字典形式defvariable_param_2(a, **b):
print(a, b)
variable_param_2(1, name="jigang.chen", age=28)  
# 1 {'name': 'jigang.chen', 'age': 28}# 可变参数-万能参数defvariable_param_2(*a, **b):  # 元组参数要放在字典参数前面print(a, b)
variable_param_2(15252162666, "徐州市", name="jigang.chen",age=28)  
# 相同类型的参数要放在一起  (15252162666, '徐州市') {'name': 'jigang.chen', 'age': 28}

五、return函数返回值详解

Python中,用 def 语句创建函数时,可以用 return 语句指定应该返回的值,该返回值可以是任意类型。需要注意的是,return 语句在同一函数中可以出现多次,但只要有一个得到执行,就会直接结束函数的执行。 函数中,使用 return 语句的语法格式如下:

return [返回值]

其中,返回值参数可以指定,也可以省略不写(将返回空值 None)。

# 多个return情况,只会有一个返回值deffun_return(a):
ifa>0:
returnTrueelse:
returnFalseresult=fun_return(1)
print(result)  # Truedeffunc_return_param(a, b):
c=a+breturnc, a, b# 会自动返回一个元组add=func_return_param(10, 20)
# 函数赋值给变量x, y, z=func_return_param(10, 20)
print(add)  # (30, 10, 20)print(x, y, z)  # 30 10 20

六、变量作用域(全局变量和局部变量)

所谓作用域(Scope),就是变量的有效范围,变量可以在哪个范围以内使用。有些变量可以在整段代码的任意位置使用,有些变量只能在函数内部使用,有些变量只能在 for 循环内部使用。 变量的作用域由变量的定义位置决定,在不同位置定义的变量,它的作用域是不一样的。本节我们只讲解两种变量: 局部变量全局变量

1.Python局部变量

在函数内部定义的变量,它的作用域也仅限于函数内部,出了函数就不能使用了,我们将这样的变量称为局部变量(Local Variable)。

# 局部变量deflocal_variable():
age=28# 函数体内定义的变量为局部变量、无法被外部调用print(f"函数体内的局部变量为:{locals()}")
deflocal_variable_2(height, weight):  # 函数传入的参数也是局部变量,只能在函数体内使用print(height, weight)
local_variable()  # {'age': 28}local_variable_2('175cm', '75kg')  # 175cm 75kg

2.Python全局变量

除了在函数内部定义变量,Python 还允许在所有函数的外部定义变量,这样的变量称为全局变量(Global Variable)。

和局部变量不同,全局变量的默认作用域是整个程序,即全局变量既可以在各个函数的外部使用,也可以在各函数内部使用。

# 全局变量name="python"defglobal_variable():
print(f"函数体内访问全局变量:{name}")
defglobal_variable_2():
globalname# 使用global修饰的变量为全局变量name="java"print(f"函数体内访问全局变量:{name}")
defglobal_variable_3():
globalwork_numberwork_number=227print(f"函数体内的全局变量为:{globals()}")
global_variable()  # pythonprint(f"函数体外访问全局变量:{name}")  # pythonglobal_variable_2()  # java 由于在函数中使用global修饰了name变量并对name再次进行了赋值,因此改变了全局变量name的值global_variable_3()  # {......'name': 'java', 'work_number': 227}print(f"函数体外的全局变量为:{globals()}")  # {......'name': 'java', 'work_number': 227}print(f"函数体外的局部变量为:{locals()}")  # 当locals()在函数体内调用,获取的是函数体内的局部变量;当locals()在函数体外调用,获取的是全局变量,作用等同于globals();

七、获取指定作用域范围中的变量

1.globals()函数

globals() 函数为 Python 的内置函数,它可以返回一个包含全局范围内所有变量的字典,该字典中的每个键值对, 键为变量名,值为该变量的值。

# 在函数体内调用defglobal_variable_3():
globalwork_numberwork_number=227print(f"函数体内的全局变量为:{globals()}")
# 在函数体外调用print(f"函数体外的全局变量为:{globals()}")

2.locals()函数

locals() 函数也是 Python 内置函数之一,通过调用该函数,我们可以得到一个包含当前作用域内所有变量的字典。 这里所谓的“当前作用域”指的是,在函数内部调用 locals() 函数,会获得包含所有局部变量的字典;

  • 当locals()在函数体内调用,获取的是函数体内的局部变量;
  • 当locals()在函数体外调用,获取的是全局变量,作用等同于globals();
# 当locals()在函数体内调用,获取的是函数体内的局部变量deflocal_variable():
age=28# 函数体内定义的变量为局部变量、无法被外部调用print(f"函数体内的局部变量为:{locals()}")
# 当locals()在函数体外调用,获取的是全局变量,作用等同于globals()print(f"函数体外的局部变量为:{locals()}")

3.vars(object)函数

vars() 函数也是 Python 内置函数,其功能是返回一个指定 object 对象范围内所有变量组成的字典。如果不传入 object 参数,vars() 和 locals() 的作用完全相同。

# 获取指定范围内的变量classdemo:
name='python'city='suzhou'print(vars(demo))  # {'__module__': '__main__', 'name': 'python', 'city': 'suzhou'...}

八、Python局部函数及用法(包含nonlocal关键字)

Python还支持在函数体内定义函数,这种被放在函数体内定义的函数称为局部函数。 在默认情况下,局部函数对外部是隐藏的,局部函数只能在其封闭(enclosing)函数内有效。

# 局部函数,形式一:在外部函数中调用内部函数deffun_a():
deffun_b():
print("i need python")
fun_b()
# 局部函数,形式二:将内部函数作为外部函数的返回值deffun_c():
deffun_d():
print("i love testing")
returnfun_d# 返回函数对象fun_a()  # i need pythonfun_cc=fun_c()  # fun_cc变量接收的是fun_c()函数的返回值,等同于fun_d,如果想要调用fun_d,使用fun_cc()即可fun_cc()  # i love testing

nonlocal关键字:内部函数本身可以直接调用外部函数的变量,但若在内部函数想要声明一个和外部函数重名的变量,需使用nonlocal关键字声明

# 局部函数:在内部函数声明和外部函数相同名称的变量--nonlocaldeffun_f():
name='python'deffun_h():
nonlocalname# 若在内部函数想要声明一个和外部函数重名的变量,需使用nonlocal关键字声明name='java'print(name)
fun_h()

九、lambda表达式(匿名函数)及用法

在定义函数的时候,不想给函数起一个名字,这个时候就可以用lambda来定义一个匿名函数,lambda 表达式, 又称匿名函数。

语法:

变量名= lambda 参数:表达式

◆ 参数:可选,通常以逗号分隔的变量表达式形式,也就是位置参数

◆ 表达式:不能包含循环、return,可以包含if...else...

可以理解 lambda 表达式,就是简单函数(函数体仅是单行的表达式)的简写版本。相比函数,lamba 表达式具 有以下 2 个优势:

  1. 对于单行函数,使用 lambda 表达式可以省去定义函数的过程,让代码更加简洁;
  2. 对于不需要多次复用的函数,使用 lambda 表达式可以在用完之后立即释放,提高程序执行的性能;
# 匿名函数--lambda# 不带参数的lambda函数deflam_1():
return1+2# 带参数的lambda函数deflam_2(x, y, z):
returnx+y+za=lambda: 1+2print(a())  # 3b=lambdax, y, z: x+y+zprint(b(1, 2, 3))  # 6

十、递归

在Python中,一个函数可以调用其他函数。函数甚至也可以调用自身,这类函数称为递归函数(Recursive Function)。如果一个函数直接或者间接地调用函数本身,那么就是递归函数。这意味着,函数将不断地调用本身并重复函数的内容,直到达到某个条件才返回一个结果。所有的递归函数都有着同样的结构,这个结构由两部分组成:基础部分,递归部分。

1.利用递归实现阶乘

# 递归# 1!=1*1# 2!=1*2# 3!=1*2*3# ...# n!=1*2*3*...*n = n * (n-1)!# 阶乘函数defrecursive_fun(n):
ifn==1:
returnnelse:
n=n*recursive_fun(n-1)
returnnprint(recursive_fun(4))  # 24

2.利用递归实现斐波那契数列

# 递归实现斐波那契数列# 1,1,2,3,5,8,13,21,34,55...# f(1)=1+0 f(2)=f(1)+1 f(3)=f(2)+f(1) f(4)=f(3)+f(2)# f(n)=f(n-1)+f(n-2)deffib3(n):
ifnotisinstance(n, int):
raiseValueError("n must be an Integer !")
elifn<0:
raiseValueError("n must greater than 0 !")
elif1<=n<=2:
return1else:
returnfib3(n-1) +fib3(n-2)
# 斐波那契数列# 1,1,2,3,5,8,13,21,34,55...deffib1(n):
i, a, b=0, 0, 1whilei<n:
a, b=b, a+bprint(a, end=" ")
i=i+1# 通过生成器实现斐波那契数列deffib2(max):
n, a, b=0, 0, 1whilen<max:
yieldba, b=b, a+bn=n+1print('Done')

十一、函数式编程介绍

函数式:

编程将一个问题分解成一系列函数,通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。 函数式编程还具有一个特点:允许把函数本身作为参数传入另一个函数,还允许返回一个函数。

高阶函数:

函数对象也可以作为参数传递给函数,还可以作为函数的返回值。参数为函数对象的函数或返回函数对象的函数称为高阶函数,即函数的函数。

1.Python map()函数

map() 函数的基本语法格式:

map(function, iterable)

其中,function 参数表示要传入一个函数,可以是内置函数、自定义函数或者 lambda 匿名函数;iterable 表示 一个或多个可迭代对象,可以是列表、字符串等。 map() 函数的功能是对可迭代对象中的每个元素,都调用指定的函数,并返回一个 map 对象,不是list。

# map()函数deffun_a(x):
returnx**2list1=range(1, 10)
new_list=list(map(fun_a, list1))
print(new_list)  # [1, 4, 9, 16, 25, 36, 49, 64, 81]

2.Python filter()函数

filter()函数的基本语法格式:

filter(function, iterable)

funcition 参数表示要传入一个函数,iterable 表示一个可迭代对象。

filter() 函数的功能是对 iterable 中的每个元素,都使用 function 函数判断,并返回 True 或者False,最后将返回 True 的元素组成一个新的可遍历的集合。

# filter()函数deffun_b(x):
returnx%2==1list2= [1, 2, 3, 4, 5, 6]
new_list1=list(filter(fun_b, list2))
print(new_list1)  # [1, 3, 5]

3.Python reduce()函数

reduce() 函数通常用来对一个集合做一些累积操作,基本语法格式为:

reduce(function, iterable)

其中,function 规定必须是一个包含 2 个参数的函数;iterable 表示可迭代对象。

注意:由于 reduce() 函数在 Python 3.x 中已经被移除,放入了 functools 模块,因此在使用该函数之前,需先导 入 functools 模块,需要引用:from functools import reduce

fromfunctoolsimportreduce# reduce()函数list3= (1, 3, 5, 7, 9)
new_list2=reduce(lambdax, y: x+y, list3)  # + - * / 均可计算print(new_list2)  # 25

总结

本篇主要介绍Python函数相关的知识,涉及到的内容比较多,总体来说分为以下几个部分:

  1. 函数的定义、调用,形参、实参的定义;
  2. 函数的传值调用和传址调用:
  • 传值调用:复制了一个副本给形参,不改变调用函数实参变量的内容;
  • 传址调用:也叫引用调用,将实参地址给形参,将改变调用函数实参变量的内容;
  1. 变量作用域:
  • 局部变量:作用域也仅限于函数内部;
  • 全局变量:作用域是整个程序;
  1. 获取指定作用域范围中的变量:
  • globals()函数:返回一个包含全局范围内所有变量的字典;
  • locals()函数:在函数体内调用,获取的是函数体内的局部变量,在函数体外调用,获取的是全局变量,作用等同于globals();
  • vars(object)函数:返回一个指定 object 对象范围内所有变量组成的字典;
  1. 局部函数:放在函数体内定义的函数称为局部函数,使用nonlocal关键字,可以在内部函数声明一个和外部函数重名的变量;
  2. 匿名函数--lambda:函数的简写版本,可以省去定义函数的过程,让代码更加简洁;
  3. 递归:利用递归实现阶乘以及斐波那契数列;
  4. Python高阶函数:
  • map()函数:对可迭代对象中的每个元素,都调用指定的函数,并返回一个 map 对象;
  • filter()函数:对可迭代对象中的每个元素,都使用函数判断,并返回 True 或者False,最后将返回 True 的元素组成一个新的可遍历的集合,通俗的说就是做数据过滤;
  • reduce()函数:通常用来对一个集合做一些累积操作;
相关文章
|
6月前
|
开发者 Python
Python中的函数式编程:理解map、filter和reduce
【2月更文挑战第13天】 本文深入探讨了Python中函数式编程的三个主要工具:map、filter和reduce。我们将详细解释这些函数的工作原理,并通过实例来展示它们如何使代码更简洁、更易读。我们还将讨论一些常见的误解和陷阱,以及如何避免它们。无论你是Python新手还是有经验的开发者,本文都将帮助你更好地理解和使用这些强大的函数。
|
1月前
|
存储 算法 数据处理
Python函数式编程
【10月更文挑战第12天】函数式编程是一种强大的编程范式,它可以帮助我们编写更加简洁、易读、可维护和高效的代码。虽然 Python 不是一种纯粹的函数式编程语言,但它提供了许多支持函数式编程的特性和功能。通过深入了解和掌握函数式编程的概念和技巧,我们可以在 Python 编程中更好地应用函数式编程的理念,提高我们的编程水平和代码质量。
15 2
|
6月前
|
分布式计算 Python
Python函数式编程学习笔记
高阶函数是能接收另一个函数作为参数的函数,如Python的map()、reduce()和filter()。map()将传入的函数应用到序列每个元素并返回迭代器,如将整数列表转换为字符串列表。reduce()对序列进行累积计算,例如求和。filter()根据给定函数返回的真值保留或丢弃序列元素,常用于筛选。sorted()函数支持自定义排序,如按绝对值或ASCII值排序。此外,还包括返回函数、匿名函数(lambda)、装饰器(用于动态增强函数功能)和偏函数(partial),用于固定函数部分参数,简化调用。
|
2月前
|
Python
Python函数式编程-Filter
Python函数式编程-Filter
|
3月前
|
Python
Python函数式编程:你真的懂了吗?理解核心概念,实践高阶技巧,这篇文章带你一次搞定!
【8月更文挑战第6天】本文介绍了Python中的函数式编程,探讨了高阶函数、纯函数、匿名函数、不可变数据结构及递归等核心概念。通过具体示例展示了如何利用`map()`和`filter()`等内置函数处理数据,解释了纯函数的一致性和可预测性特点,并演示了使用`lambda`创建简短函数的方法。此外,文章还强调了使用不可变数据结构的重要性,并通过递归函数实例说明了递归的基本原理。掌握这些技巧有助于编写更清晰、模块化的代码。
36 3
|
4月前
|
存储 分布式计算 索引
Python函数式编程入门窥探
Python本身不是一门函数式编程语言,但是它参考了一些函数式编程语言很好的地方,除了可以写出更可读的代码外。还能用它来实现一些特定功能,本身也提供了强大的注解系统和函数和对象之间的灵活调用。
|
4月前
|
缓存 并行计算 Shell
12种增强Python代码的函数式编程技术
函数式编程是一种高度抽象的编程范式,它倡导使用纯函数,即那些不依赖于外部状态、没有可变状态的函数。在纯粹的函数式编程语言中,函数的输出完全由输入决定,因此相同的输入总是产生相同的输出,这样的函数我们称之为无副作用的。
|
5月前
|
Python
在Python中,`map()`, `filter()` 和 `reduce()` 是函数式编程中的三个核心高阶函数。
【6月更文挑战第24天】Python的`map()`应用函数到序列元素,返回新序列;`filter()`筛选满足条件的元素,生成新序列;`reduce()`累计操作序列元素,返回单一结果。
39 3
|
5月前
|
Serverless 开发者 Python
Python函数式编程:让你的代码更简洁、更高效!
【6月更文挑战第12天】Python函数式编程引入了数学函数概念,强调无副作用和不可变数据。特点包括高阶函数、Lambda表达式、map、filter和reduce。示例展示了如何使用map进行平方运算,filter筛选条件元素,reduce计算元素总和,体现其简洁高效。虽然不适用于所有情况,但函数式编程能提升代码可读性和可维护性。
32 3
|
6月前
|
Python
Python函数式编程自带函数
Python函数式编程自带函数
30 1