Python基础知识总结笔记(四)函数
- python中的函数
- 函数中的参数
- 变量作用域
- 偏函数PFA
- 递归函数
- 高阶函数
- BIFs中的高阶函数
- 匿名函数lambda
- 闭包Closure
- 装饰器Decorator
- 函数式编程Functional Programming
1. python中的函数
■ 函数的意义:
■1.对输入进行变换映射后输出 ,可以进行反复调用
■2.过程化 VS 结构化
■ 函数的创建及结构:
■定义函数名:def foo1(num):
■参数:num
■函数体
■返回
□有无返回:
有返回值:return返回的是对象,(如返回对象数>1返回元组)
无返回值 :无返回值或者return后为空。
print可以有很多,但是return只有一个。
□return与yield的区别:
print:不返回任何的函数
return 结束函数,返回值,当函数被调用时,遇到结尾或return时就准备结束了。
yield:丢出一个数,对象变成了生成器–记录当前运行到哪里了。
#函数的意义
n=5
for i in range(n):
print(i)
# 以函数名对以上代码块进行封装
def foo(num): #函数名foo; 参数num
for i in range(num):
print(i)
#然后进行反复调用
# foo()
#对输入进行变换映射后输出
#函数的定义
def foo1(num):#函数名与参数
#函数体
cumsum=0#函数内部的变量
for i in range(num):
cumsum+=i
#返回值
return cumsum
foo1(15)
#函数的返回值-无返回值
def foo2():#函数名与参数
#函数体
cumsum=0
for i in range(15):
cumsum+=i
#无返回值
#或者return后为空
foo2()
#函数的返回值,有返回值
def foo3():#函数名与参数
#函数体
cumsum=0
for i in range(15):
cumsum+=i
#return返回的是对象,(如返回对象数>1返回元组)
return cumsum,cumsum*2
#函数结束
foo3()
#return与print在Notebook上的差异
#print可以有很多,但是return只有一个
# def foo2():
# for i in range(5):
# print(i)
# foo2()
# #函数的参数
# def foo3(num):
# for i in range(num):
# print(i)
# return 'Done'
# foo3(1)
# print(foo3(2))
### 函数的返回
#return与yield关键字
#return 结束函数
def foo1():#不返回任何的函数
print('i\'m foo1,but i return nothing')
def foo2():#使用return返回值
return 'i\'m foo2, this is what i return'
def foo3():#函数被调用时,遇到结尾或return时就准备结束了。
return 'i\'m foo3, this is the first return'
return 'i\'m foo3, this is the secod return'
#yield 丢出一个数--对象变成了生成器--记录当前运行到哪里了
def foo4():
for i in range(5):
return i#执行第一次时foo4函数就结束了
#yield
def foo4():
for i in range(5):
yield i
yield 'f' #再加入一个yield看看会不会被执行
i+=1
g1=foo4()#看一下调用foo4()返回的是什么
type(g1)#看一下g1是个什么样子的对象
next(g1)#继续上一次的位置,进入下一层循环
#执行完最后一次循环,结束 yield语句并抛出StopIteration 异常
2. 函数中的参数
■ 参数:
■语法:
func(positional_args,keyword_args,*tuple_nonkw_args,**dict_kw_args)
positional_args位置参数
keyword_args关键字参数
tuple_nonkw_args非关键字不定长参数
dict_kw_args关键字不定长参数
■ 按参数传递方式:
■位置参数(定位参数,非关键字参数) :位置顺序十分重要,不可缺少。对位置敏感,传递时不用指定参数名
■关键字参数:等于号确定。
不传关键字参数,函数依旧可以被调用,采用默认值。传关键字参数,覆盖默认值。
■位置参数包裹及使用*
:一次传入不定长个位置参数。传入n个位置参数。
■关键字参数包裹及使用 **
:一次性传入不定长关键字参数传入n个关键字参数。
位置参数包裹可以写n个——列表;关键字参数包裹可以写n个——字典
■包裹解包顺序:首先拆位置参数包裹,按顺序给必选,默认,可变。再抓给关键字参数包裹。
■传递不定长参数时,使用包裹:位置参数
■传递参数时,使用包裹:关键字型参数
传递不定长参数时使用包裹——位置参数必须打碎(只传递内容)再传递,传递参数同理。即:列表类型必须(*list);字典类型必须( * *字典)。若传(list)代表的是传对象对不上函数。
■ 按参数的类型:
■必选(位置参数):必须写、个数要对应
■关键字/默认:*args可变长位置参数,**kwargs可变长关键字参数
其中:
*args列表
**kwargs字典
■ 函数如何处理传入参数
■值传递参数与指针传递参数:
值传递参数:值传递时,变量传递给函数后,函数复制一份,不会影响原有变量。
指针传递参数,会修改参数本身:指针(或引用)传递时,变量传递给函数的是及引用,该引用可以改变原变量
#按参数传递方式
#位置参数
def foo3(companyName,websiteUrl):#位置参数的定义
print('公司名:',companyName,'公司网址:',websiteUrl)
foo3('七月在线','http://www.julyedu.com')
foo3('http://www.julyedu.com',websiteUrl='七月在线')
#位置参数,对位置敏感,传递时不用指定参数名
#关键字参数
def foo4(companyName,websiteUrl,intro='专注AI教育'):#关键字参数的定义intro='专注AI教育'
print('公司名:',companyName,'公司网址:',websiteUrl,'介绍:',intro)
foo4('七月在线','http://www.julyedu.com')#不传关键字参数,函数依旧可以被调用,采用默认值
foo4('七月在线','http://www.julyedu.com',intro='国内领先的AI教育平台')#传关键字参数,覆盖默认值
#如果想一次传入不定长个位置参数,怎么办呢?
#位置参数包裹及使用*
def mysum1(a,b,c):
return a+b+c
mysum1(5,7,15)
#mysum1(5,7) #报错,因为传入的参数少于函数定义时的个数
#mysum1(5,7,15,22) #报错,因为传入的参数多于函数定义时的个数
#这时我们就需要使用包裹*args(tuple类型)进行接收
#位置参数包裹可以写n个——列表;关键字参数包裹可以写n个——字典
def mysum2(*args):
# print(type(args))
return sum(args)
mysum2(5,7,15,22,33)#正常调用
mysum2(5,7)#正常调用
#那同样如果想一次性传入不定长关键字参数,也可以使用一个包裹进行接收
#关键字参数包裹及使用**
def filmInfo(**kwargs):
print(type(kwargs))
for key,values in kwargs.items():
print(key,':',values)
filmInfo(film='羞羞的铁拳',box=3.5)
filmInfo(film='羞羞的铁拳',box=3.5,rate=7.9)
# d1={'羞羞的铁拳':3.5,'box':3.5}
#包裹解包顺序
#首先拆位置参数包裹,按顺序给必选,默认,可变。
#再抓给关键字参数包裹
def scoreReport(name,age,*args,course='python',**kwargs):
#位置;位置;位置参数包裹;关键字(默认,可以不修改);关键字参数包裹
#位置参数包裹可以写n个——列表;关键字参数包裹可以写n个——字典
print('个人信息:',name,age)
for item in args:
print(item)
print('课程信息:',course)
print('每节课成绩:')
for key,value in kwargs.items():
print (key,value)
scoreReport('xiaoming',22,'高中部','三年二班',Lesson1=80,Lesson2=85)
scoreReport('xiaoming',22,'三年二班',course='machine learning',Lesson1=80,Lesson2=85)
# #传递不定长参数时使用包裹-位置参数 必须打碎(只传递内容)再传递,即列表类型必须(*list);字典类型必须(**字典)。若(list)代表的是传对象对不上函数。
l1=[1,5,6,7,2,5,3.5,9,6,3,4]
mysum2(*l1)#=mysum2(1,5,6,7,2,5,3.5,9,6,3,4)
# #zip案例
# l1=[(1,3),(2,4)]
# list(zip(*l1))
# ##传递参数时使用包裹-关键字型参数
# d1={'羞羞的铁拳':3.5,'雷神3':3.1,'战狼2':60}
# filmInfo(**d1)
#值传递,参数本身不会被修改
a=7
b='julyedu'
print('before reference:',a,b)
def foo1(a,b):
a+=1
b+='.com'
print('In foo1 a,b has changed to',a,b)
foo1(a,b)
print('after reference:',a,b)
#结论:值传递时,变量传递给函数后,函数复制一份,不会影响原有变量
print('>'*40)
#指针传递参数,会修改参数本身
l1=[1,2,3.4]
d1={'name':'jack'}
def foo2(a,b):
a.pop()
b['age']=22
print('before reference:',l1,d1)
foo2(l1,d1)
print('after reference:',l1,d1)
#结论:指针(或引用)传递时,变量传递给函数的是及引用,该引用可以改变原变量
3. 变量作用域
■ 标识符的作用域
globals()#全局变量名称空间
locals()#局部变量名称空间
■ 全局变量
■定义:全局变量会一直存在,除非是脚本运行结束或 del 删除它。
■经过函数时:可以被函数内部调用
■ 局部变量
■函数内部创建与访问,当被调用结束时,生命周期结束。
■ 变量的搜索顺序
■覆盖问题:重名,从局部到全局:先从局部找,找不到再去全局找。
■局部作用域->全局作用域:从局部到全局
4. 偏函数PFA
■ 偏函数Partial function application
■使用场景:如果一个函数的参数很多,而在每次调用的时候有一些又经常不需要被指定时,就可以使用偏函数(近似理解为默认值)有些参数无需修改
■语法:partical(func,*args,**keywords)
■使用:from functools import partial
■原理:创建一个新函数,固定住原函数的部分参 数(可以为位置参数,也可以是关键字参数)
5. 递归函数
■ 定义:
■函数在内部调用自身
■ 例子:
■求一个列表中数值的累加
6. 高阶函数
■ 函数的引用与调用
■引用:访问,变量别名(多个别名引用)
■调用:()
■ 函数对象既然可以被引用,那可以作为参数被传入或作 为结果被返回吗?
■ 高阶函数:
■一个函数接收另一个函数作为参数
■ 回调函数:
■函数作为调用函数的结果返回
7. BIFs中的高阶函数
■ filter
■核心点:对每个元素做过滤
■ map
■核心点:对每个元素做映射
■ reduce
■核心点:两两传给func
■Python 3.x中,reduce()函数已经被从全局名字 空间里移除了,它和partical一样被放置在 fucntools模块中。使用前需要调用.
8. 匿名函数lambda
■ 匿名函数lambda:
■使用场景:
□返回简单结束 ,不需要专门定义函数
■特点:
□简洁,同一行定义体+声明。不用写return
■定义:
□定义后,赋值给一个变量,做正常函数使用
□lambda关键字定义在高阶函数的参数位上
■语法:
□lambda(args1,args2, argsN):expression
9. 闭包Closure
■ 闭包的概念
■涉及嵌套函数时才有闭包问题
■内层函数引用了外层函数的变量(参数),然后 返回内层函数的情况,称为闭包(Closure)。
■这些外层空间中被引用的变量叫做这个函数的环 境变量。
■环境变量和这个非全局函数一起构成了闭包。
■ 闭包的特点:
■函数会记住外层函数的变量
■ 闭包的实现:
10. 装饰器Decorator
■ 定义:
■以函数作参数并返回一个替换函数的可执行函数
■ 简单理解:
■装饰器的作用就是为已存在的对象添加额外功能
■为一个函数增加一个装饰(用另一个函数装饰)
■本质上就一个返回函数的高阶函数
■ 应用:
■给函数动态增加功能(函数)
■ 定义与使用:
11. 函数式编程Functional Programming
■ 函数式编程思想:
■函数是第一等公民First Class
■函数式编程是一种编程范式,是如何编写程度的方法论。 把运算过程尽量变成一系列函数的调用。属于结构化编程
■ 特点:
■允许函数作为参数,传入另一个函数
■返回一个函数
■ 理解:
■结合本章知识点,案例进行理解