Python基础知识总结笔记(四)函数

Python基础知识总结笔记(四)函数

  1. python中的函数
  2. 函数中的参数
  3. 变量作用域
  4. 偏函数PFA
  5. 递归函数
  6. 高阶函数
  7. BIFs中的高阶函数
  8. 匿名函数lambda
  9. 闭包Closure
  10. 装饰器Decorator
  11. 函数式编程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
■函数式编程是一种编程范式,是如何编写程度的方法论。 把运算过程尽量变成一系列函数的调用。属于结构化编程
■ 特点:
■允许函数作为参数,传入另一个函数
■返回一个函数
■ 理解:
■结合本章知识点,案例进行理解

发布了193 篇原创文章 · 获赞 221 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/qq_37486501/article/details/104390938