一、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 个优势:
- 对于单行函数,使用 lambda 表达式可以省去定义函数的过程,让代码更加简洁;
- 对于不需要多次复用的函数,使用 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函数相关的知识,涉及到的内容比较多,总体来说分为以下几个部分:
- 函数的定义、调用,形参、实参的定义;
- 函数的传值调用和传址调用:
- 传值调用:复制了一个副本给形参,不改变调用函数实参变量的内容;
- 传址调用:也叫引用调用,将实参地址给形参,将改变调用函数实参变量的内容;
- 变量作用域:
- 局部变量:作用域也仅限于函数内部;
- 全局变量:作用域是整个程序;
- 获取指定作用域范围中的变量:
- globals()函数:返回一个包含全局范围内所有变量的字典;
- locals()函数:在函数体内调用,获取的是函数体内的局部变量,在函数体外调用,获取的是全局变量,作用等同于globals();
- vars(object)函数:返回一个指定 object 对象范围内所有变量组成的字典;
- 局部函数:放在函数体内定义的函数称为局部函数,使用nonlocal关键字,可以在内部函数声明一个和外部函数重名的变量;
- 匿名函数--lambda:函数的简写版本,可以省去定义函数的过程,让代码更加简洁;
- 递归:利用递归实现阶乘以及斐波那契数列;
- Python高阶函数:
- map()函数:对可迭代对象中的每个元素,都调用指定的函数,并返回一个 map 对象;
- filter()函数:对可迭代对象中的每个元素,都使用函数判断,并返回 True 或者False,最后将返回 True 的元素组成一个新的可遍历的集合,通俗的说就是做数据过滤;
- reduce()函数:通常用来对一个集合做一些累积操作;