函数 认识函数 模块化编程指的是把程序进行封装(函数封装、面向对象、文件)
函数 函数是具有特定功能的代码块 function 函数就是把代码进行封装、以提高代码的重用性、提高开发效率、降低了后期的维护成本
函数的定义和使用
1 2 3 4 5 6 def 函数名 (参数列表 ): 具体功能代码 函数名()
函数封装并不会执行,只是把函数定义了而已 如果想使用定义的函数,就用语法来进行函数调用 函数定义后,不调用不执行 不能在函数定义前调用函数 函数的调用不受次数影响 函数的命名要遵守命名规范
函数的参数
函数在定义时,可以在参数列表的位置定义 形式参数(形参)
如果函数有形参,那么在调用的时候必须传递参数 实际参数(实参)
实参将数值传递给形参的过程,就是变量的赋值操作
函数定义了几个参数,调用的时候就要按指定顺序进行参数的传递
普通参数、默认参数
1 2 3 4 5 def cook (food:str ): print (f"今晚吃{food} " ) cook("noodle" )
在有多个参数的时候,靠后的称为默认参数,默认参数可以指定默认值,在调用的时候可以不传实参
默认参数只能靠后
1 2 3 4 5 def cook (food, dirnk="wine" , snack="chips" ): print (f"今晚吃{food} ,今晚喝{dirnk} ,饭后甜点是{snack} " ) cook("rice" )
收集参数 定义一个形参,专门收集多余的实参,或者说是不确定需要接受多少个实参的情况下,使用一个实参来接收,这个形参用*args
args 接收的参数以元组的形式存储
这个变量不一定非得是 args,可以是 num 等等,但是记得是一个星号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def calc (x='+' , *args ): print (type (args)) res = 0 if x == '+' : for i in args: res += i print (f"{args} 求和得{res} " ) elif x == '-' : res = 2 * args[0 ] for i in args: res -= i print (f"{args} 求差得{res} " ) else : print ("符号错误" ) calc("+" , 200 , 100 , 300 ) calc("-" , 200 , 100 , 300 )
命名关键字参数
命名关键字参数,定义在收集参数 后面
关键字参数必须通过形参的名字来传递
1 2 3 4 5 6 def cook (food, *other, time ): print (f"we are going to eat {food} and {other} at {time} " ) cook("rice" , "wine" , "snack" , time="dinner" ) cook("rice" , "wine" , "snack" , "dinner" )
关键词收集参数
普通收集参数*args 会把接收到的参数收集成为 元组
关键词收集参数**kwargs 会将接收到的关键字参数收集成为 字典
1 2 3 4 5 6 def cook (food, *other, time, **kwargs ): print (f"we are going to eat {food} and {other} at {time} with {kwargs} " ) cook("rice" , "wine" , "snack" , time="dinner" , data='2.2' , year='2022' )
形参声明的位置 普通参数、默认参数、收集参数、关键字参数、关键字收集参数
函数的返回值 一个函数除了可以完成一定功能外,还可以按需要返回一定内容 函数中使用 return 关键字来指定返回数据,可以返回任何类型的数据 函数的返回值,会把数据返回到调用的位置
1 2 3 4 5 6 7 8 9 def calc_plus (*args ): res = 0 for i in args: res += i return res result = calc_plus(123 , 234 , 345 , 456 ) print (f"所有数值计算结果是:{result} " )
函数中可以使用 return 返回数据或任意内容
return 意味着函数的结束,return 之后的代码不再执行
函数的返回值可以有,可以没有,当没有返回值的时候,返回的是 None
变量的作用域 作用域就是当前起作用、可用的范围区域 变量的有效范围
全局变量 :在函数内外都可以使用的变量
局部变量 :在函数内部可以使用的变量
在函数内部可以获取函数外部的变量(即全局变量)中的不可变数据类型,仅能访问,不能修改
1 2 3 4 5 6 7 8 9 10 11 12 num = 10 def func (): print (num) func() num = 10 def func (): num += 20 print (num) func()
在函数内部可以对全局变量的可变数据类型(列表、字典),进行修改和访问
1 2 3 4 5 6 7 8 9 10 11 varl = [1 , 2 , 3 ] def func (): print (varl) varl.append(4 ) print (varl) varl[2 ] = 'a' print (varl) func() print (varl)
在函数内部定义的变量,只能在函数内部使用,可获取,可修改,函数外部无法访问
1 2 3 4 5 6 def func (): res = 20 res += 10 print (res) func() print (res)
在函数内部使用 global 声明的变量,可将其改为全局变量
1 2 3 4 5 6 7 def func (): global res res = 20 res += 10 print (res) func() print (res)
在函数外部定义的变量,想要在函数内部修改,可以在函数内部将其声明为全局变量
1 2 3 4 5 6 num = 10 def func (): global num num += 20 print (num) func()
1 2 3 4 5 6 7 8 9 def outer (): print ("This is a outer function..." ) def inner (): print ("This is a inner function..." ) inner() outer() print (globals ())
- `locals()`:获取局部数据
局部函数:在函数内部定义的函数,称为局部函数
全局函数:相对于局部函数的外部函数
1 2 3 4 5 6 7 8 9 def outer (): print ("This is a outer function..." ) def inner (): print ("This is a inner function..." ) inner() outer()
1 2 3 4 5 6 7 8 9 10 { '__name__' : '__main__' ,'__doc__' : None ,'__package__' : None ,'__loader__' : <_frozen_importlib_external.SourceFileLoader object at 0x108786550 >,'__spec__' : None ,'__annotations__' : {},'__builtins__' : <module 'builtins' (built-in )>,'__file__' : '/Users/zachary/PycharmProjects/Python教程阶段1/code/30变量的作用域.py' ,'__cached__' : None , 'outer' : <function outer at 0x1087f9710 >}
main :当前脚本如果作为主程序,那么值是main ,如果是当做一个模块,在另外一个脚本中引用去使用模块的名字。
doc :当前脚本的文档说明 在当前脚本当中的第一个三引号’’’’’’注释的就是当前脚本的说明文档
nonlocal 关键字
在内函数中,使用上一层函数中的局部变量,可以在内函数中,使用 nonlocal 声明一下变量,即可以在内函数中使用外函数的局部变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def outer (): num = 10 print ("This is a outer function..." ) def inner (): nonlocal num num += 10 print ("This is a inner function..." ) print (num) inner() outer()
函数封装的练习题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def jiujiu (n=0 ): ''' 打印九九乘法表 :param n: 控制打印输出顺序,n默认为0时,正向输出;否则,逆向输出 :return: 无返回值 ''' if n == 0 : r = range (1 ,10 ) else : r = range (9 ,0 ,-1 ) for i in r: for j in range (1 ,i+1 ): print (f"{j} ×{i} ={i*j} \t" ,end="" ) print () print () jiujiu() jiujiu(-1 )
练习二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 def juxing (n=0 , x=10 , y=10 ): ''' :param n: 当n为默认值0时候。打印实心矩形,否则打印空心的矩形 :param x: 控制矩形行数 :param y: 控制矩形列数 :return: 无返回值 ''' for i in range (x): if i == 0 or i == x - 1 : print ("# " * y) else : if n == 0 : print ("# " * y) else : print ("# " + " " * (y - 2 ) + "#" ) print () juxing(x=9 , y=16 ) juxing(n=-1 ,x=10 ,y=10 )
递归函数 递归函数就是定义了一个函数,这个函数内部自己调用函数本身 递归函数内必须要有结束条件,否则会一直调用直至栈溢出 递归函数会一层一层进入,再一层一层返回
1 2 3 4 5 6 7 8 9 def jiecheng (n ): print (n) if n == 0 : return jiecheng(n-1 ) print (n) jiecheng(5 )
实现阶乘 1 2 3 4 5 6 7 8 9 def jiecheng (n ): if n == 1 : return 1 return int (n) * jiecheng(n-1 ) res = jiecheng(10 ) print (res)**
实现斐波那契数列 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def fibo (n ): if n == 1 : return 0 elif n == 2 : return 1 else : return fibo(n - 1 ) + fibo(n - 2 ) print (fibo(5 )) res = 0 for i in range (5 ): res += fibo(i + 1 ) print (res)
回调函数 如果一个函数中要求传递的参数是一个函数,并且在函数中使用了传递进来的函数,那么这个被调用的函数就是回调函数
1 2 3 4 5 6 7 8 9 10 11 12 def func (f ): print ("func这是调用了回调函数的函数" ) f() def cal (): print ("cal这是一个回调函数" ) func(cal)
再来一个例子
1 2 3 4 def fun (x,y,f ): print (f(x,y)) fun(2 ,3 ,pow )
闭包函数 如果在一个函数中,返回了一个函数。并且这个函数是内函数,该内函数使用了外函数中的局部变量(这意味着需要使用 nonlocal) ,这就是闭包函数 保护了外函数中的局部变量,既可以使用,也不会被破坏 可以使用closure 魔术方法查看是否闭包函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def person (): money = 0 def work (): nonlocal money money += 100 print (money) return work res = person() res() res() res() print (res.__closure__) print (person.__closure__)
匿名函数——lambda 表达式 匿名函数即,可以不使用 def 定义,并且这个函数也没有名字 在 Python 中使用 lambda 表达式来定义匿名函数 lambda 仅仅是一个表达式,不是一个代码块 lambda 表达式也有形参,并且不能访问除了自己的形参以外的任何变量(包括全局变量) 功能相对单一,不能写太复杂的形式 lambda [参数列表]:返回值
1 2 res = lambda x, y: x + y print (res(4 , 4 ))
同样的,lambda 表达式也可以用于封装带有分支结构的函数,很便捷
1 2 3 4 5 6 7 8 9 10 11 12 def func (gender ): if gender == 'male' : return '男性' else : return '女性' res = func("female" ) print (res)res = lambda gender:'男性' if gender=='male' else '女性' print (res("female" ))
迭代器 迭代器是 Python 中的特色功能,用于访问元素的一种方式 迭代器是一个可以记住访问遍历的位置的对象 从集合的第一个元素开始访问,直到集合中的所有元素被访问完毕 迭代器只能从前往后一个一个遍历的,不能后退 迭代器是一个能被next()函数 调用,并不断返回下一个值的对象称为迭代器(Iterator)对象
功能:把可迭代对象,转为一个迭代器对象 参数:可迭代的对象(str、list、tuple、dict、set、range…) 返回值:迭代器对象 注意:迭代器对象一定是可迭代对象,但是可迭代对象不一定是迭代器对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 player = ['Curry' , 'Kobe' , 'James' , 'Irving' ] res = iter (player) p = next (res) print (p) p = next (res) print (p) p = next (res) print (p) p = next (res) print (p) p = next (res) print (p)
通过使用 list()方法直接取出迭代器中的所有数据
1 2 3 4 5 6 player = ['Curry' , 'Kobe' , 'James' , 'Irving' ] res = iter (player) li = list (res) print (li)
1 2 3 4 5 6 player = ['Curry' , 'Kobe' , 'James' , 'Irving' ] res = iter (player) for i in res: print (i)
迭代器有一个特点,无论是使用上述三种方法哪一种取,取过一次数据后,数据就丢失去了,想要再次使用就不行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 player = ['Curry' , 'Kobe' , 'James' , 'Irving' ] res = iter (player) for i in res: print (i) for i in res: print (i)
判断一个对象是否是可迭代的或者是否迭代器对象,需要使用 from collections.abc import Iterable,Iterator
当需要判断一个对象类型的时候,可以使用 type()
当需要判断一个对象是否某一类型的时候可以使用 isinstance()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from collections.abc import Iterable, Iterators = "abdef" r1 = isinstance (s, int ) r2 = isinstance (s, str ) print (r1, r2) player = ['Curry' , 'Kobe' , 'James' , 'Irving' ] i = iter (player) r1 = isinstance (s, Iterator) r2 = isinstance (s, Iterable) r3 = isinstance (i, Iterator) r4 = isinstance (i, Iterable) print (r1, r2, r3, r4)
生成器 yield 关键字 使用了yield关键字的函数——生成器函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def output (): print ("res 1" ) yield 1 print ("res 2" ) yield 2 print ("res 3" ) yield 3 o = output() res = next (o) print (res)res = next (o) print (res)res = next (o) print (res)for res in o: print (res)
可以将该函数理解为一个 可迭代对象
yield 关键字使用在 生成器函数中
yield 和函数中的 return 相似
共同点:都会返回结果
不同点:
return 会返回结果,并结束当前函数的调用,后面的代码不再执行
yield 会返回结果,并记住当前代码的执行位置,下一次调用的时候会从上一次离开的位置继续向下执行
调用函数后结果是一个生成器,需要使用收集迭代器的方法进行数据收集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 def hello (): print ('Hello sen1' ) return 1 print ('Hello sen2' ) return 2 res = hello() print (res) res = hello() print (res) def hello_y (): print ('Hello sen1' ) yield 1 print ('Hello sen2' ) yield 2 res = hello_y() print (res)temp = next (res) print (temp) temp = next (res) print (temp) res = hello_y() print (list (res)) res = hello_y() for i in res: print (i)
yield from
1 2 3 4 5 6 7 8 9 10 11 12 def yield_func (num: int ): for i in range (num): yield square(i+1 ) def call_yield_func (): yield from yield_func(3 ) yield from yield_func(5 ) for item in call_yield_func(): print (item)
生成器 send 相当于使用 next,并将数据送回给生成器(有种协程的感觉)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def yield_send_func (): number = yield "welcome a square function" while True : number = yield square(number) if number is None : break generator = yield_send_func() print (next (generator))for i in range (1 ,11 ): if i == 10 : try : generator.send(None ) except StopIteration: break print (generator.send(i))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 def yield_square_func (): number = yield "welcome a square function" while True : number = yield square(number) if number is None : break def yield_cube_func (): number = yield "welcome a cube function" while True : number = yield number ** 3 if number is None : break def choose_func (): item = yield "please choose 1 for square or 2 for cube" while True : if item == 1 : yield from yield_square_func() elif item == 2 : yield from yield_cube_func() else : break generator = choose_func() print (next (generator))print (generator.send(int (input ())))for i in range (1 , 11 ): if i == 10 : try : generator.send(None ) except StopIteration: break else : print (generator.send(i))
练习题 使用生成器改写斐波那契数列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def fibo (x ): a, b = 0 , 1 yield a for i in range (x - 1 ): yield b a, b = b, a + b i = int (input ("请输入一个整数:" )) res = fibo(i) for i in res: print (i,end=',' )
内置函数 内置函数就是在系统安装完 Python 解释器时,由解释器提供好的函数
range 函数 range 函数功能:能够生成一个指定的数字序列 参数:[start,stop,(step)] start:开始的值,默认为 0 stop:结束的值,对于[start,stop)是一个左闭右开区间,stop 选不到的 step:默认为 1,负数为倒着步进 返回值:可迭代对象,数字序列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from collections.abc import Iterablefrom collections.abc import Iteratorres = range (10 ) print (res) print (isinstance (res, Iterable)) print (isinstance (res,Iterator)) print (list (res))for i in res: print (i) it = iter (res) print (next (it)) for i in it: print (i)
zip()函数 zip()函数功能:可以接收多个可迭代对象,然后把每个可迭代对象中第 i 个元素组合在一起,形成一个新的迭代器(元组),当输入的可迭代对象中,最短的一个被耗尽时,迭代器将停止迭代。 参数:*iterables,任意个的可迭代对象 返回值:返回一个元组的迭代器 既然使用 zip 生成的结果是一个迭代器,那么获取数据的时候就可以使用 next、for、list 等方法获取,依旧是使用一次 少一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 var1 = "1234" var2 = ['a' , 'b' , 'c' , 'd' ] var3 = ('A' , 'B' , 'C' , 'D' ) res = zip (var1, var2, var3) print (res, type (res))print (next (res)) print (next (res)) res = zip (var1, var2, var3) for i in res: print (i) """ ('1', 'a', 'A') ('2', 'b', 'B') ('3', 'c', 'C') ('4', 'd', 'D') """ res = zip (var1, var2, var3) print (list (res))
可以使用 zip(*zip)执行一个反向操作
1 2 3 4 5 6 7 x = [1 , 2 , 3 ] y = [4 , 5 , 6 ] zipped = zip (x, y) print (list (zipped)) x2, y2 = zip (*zip (x, y)) print (x2, y2)
其他内置函数 数据类型转换相关内置函数
int() 将其他数据类型转为整型
float() 转为浮点类型
bool() 转为布尔类型
complex() 转为复数
str() 转为字符串类型
list() 转为列表类型
tuple() 转为元组类型
dict() 转为字典类型
set() 转为集合类型
变量相关函数
id() 获取当前数据的 ID 标识
type() 获取当前数据的类型字符串
print() 数据的打印
input() 获取输入的数据
isinstance() 检测是否为指定的数据类型
数学相关函数
abs() 返回一个数的绝对值,如果是复数,返回模
sum() 从左向右对一个 iterable 对象中的项求和并返回,开始值不允许为字符串
max() 获取最大值
min() 获取最小值
pow() 次幂运算
round() 四舍五入
1 2 3 4 5 6 7 8 9 10 11 12 13 print (abs (-99.99 )) print (sum ([1 , 2 , 3 ])) print (max (9 , 90 , 999 )) print (min (9 , 90 , -99 )) print (pow (2 , 3 )) r = 3.1415926 print (round (r)) print (round (r, 4 ))
进制相关函数及字符集 进制转换
bin() 将数值类型转换为二进制
int() 将二进制转换为整型
oct() 将数值类型转换为八进制
hex() 将数值类型转为十六进制
1 2 3 4 5 6 7 8 9 10 11 print (bin (123 )) print (int (0b1111011 )) print (oct (123 )) print (int (0o173 )) print (hex (123 )) print (int (0x7b ))
Ascii 码是 基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言,共计 128 个字符 常用的包括:GB2312-80、GBK、GBK18030、Unicode(UTF-8) ascii 字符转换 A-Z:65-90 a-z:97-122 0-9:48-57
将字符转为 ASCII:ord()
将 ASCII 转为字符:chr()
1 2 3 4 5 a = ord ('a' ) print (a) c = chr (97 ) print (c)
高阶函数——sorted()
sorted(iterable,[reverse,key])
运行原理:把可迭代数据里面的元素,一个一个取出来,放到 key 这个函数中进行处理,并按照函数中 return 的结果进行排序,返回一个新的列表
功能:排序
参数:
iterable 可迭代的数据(容器类型数据,range 数据序列,迭代器)
reverse 可选,是否反转,默认为 False,不反转,True 反转
key 可选,函数,可以是自定义函数,也可以是内置函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 arr = [3 , 7 , 1 , -9 , 20 , 10 ] print (sorted (arr)) print (sorted (arr, reverse=True )) print (sorted (arr, key=abs )) def func (num ): return num % 2 arr = [3 , 2 , 4 , 6 , 5 , 7 , 9 ] res = sorted (arr, key=func) print (res) res = sorted (arr, key=lambda x: x % 2 ) print (res)
高阶函数——map()
*map(func, __iterables)
功能:对传入的可迭代数据中的每个元素进行处理,返回一个新的迭代器
参数:
func 函数:自定义函数|内置函数
iterables:可迭代的数据
返回值:迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 arrlist = ['1' , '2' , '3' , '4' ] newlist = [] for i in arrlist: newlist.append(int (i)) print (newlist) res = map (int , arrlist) print (list (res)) arrlist = [1 , 2 , 3 , 4 ] newlist = [] for i in arrlist: newlist.append(i ** 2 ) print (newlist) def power (num ): return num ** 2 arrlist = [1 , 2 , 3 , 4 ] res = map (power, arrlist) print (list (res)) arrlist = [1 , 2 , 3 , 4 ] res = map (lambda x: x ** 2 , arrlist) print (list (res)) arrlist = ['a' , 'b' , 'c' , 'd' ] res = map (lambda x: ord (x.upper()), arrlist) print (list (res))
高阶函数——reduce()
reduce(function, sequence[, initial])
使用需要导入 from functools import reduce
功能:每一次从 sequence 即一个 iterable 拿出两个元素,放入到 func 函数中进行处理,得出一个计算结果,然后把这个计算结果和 iterable 中的第三个元素,继续放到 func 函数中国进行运算,以此类推,直到所有元素都参与了运算
参数
function 函数:内置函数|自定义函数
sequence:是一个 iterable,可迭代数据
返回值:最终的运算处理结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 from functools import reducenumlist = [1 , 2 , 3 , 4 , 5 ] res = reduce(lambda x, y: x + y, numlist) print (res) numlist = [5 , 2 , 1 , 1 ] num = '' for i in numlist: num += str (i) res = int (num) print (res, type (res)) def func (x, y ): return x * 10 + y res = reduce(func, numlist) print (res, type (res)) res = reduce(lambda x, y: x * 10 + y, numlist) print (res, type (res)) num = '456' strdict = {'0' : 0 , '1' : 1 , '2' : 2 , '3' : 3 , '4' : 4 , '5' : 5 , '6' : 6 , '7' : 7 , '8' : 8 , '9' : 9 } res1 = map (lambda x: strdict[x], num) res2 = reduce(lambda x, y: x * 10 + y, res1) print (res2) num = '456' strdict = {'0' : 0 , '1' : 1 , '2' : 2 , '3' : 3 , '4' : 4 , '5' : 5 , '6' : 6 , '7' : 7 , '8' : 8 , '9' : 9 } print (reduce(lambda x, y: x * 10 + y, map (lambda x: strdict[x], num)))
高阶函数——filter()
filter(func,iterable)
功能:过滤数据,将 iterable 中的每个元素拿到 fun 函数中进行处理,如果函数返回 True 则保留这个数据,返回 False 则,丢弃这个数据
参数
func 函数:自定义函数|内置函数
iterable:可迭代的数据
返回值:保留下来的迭代器数据
1 2 3 4 numlist = [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] res = filter (lambda x: True if x % 2 == 0 else False , numlist) print (list (res))
更新: 2024-01-16 03:26:11 原文: https://www.yuque.com/zacharyblock/cx2om6/iygqmxqyo52f37yc