Python笔记11-函数、返回值、匿名函数

一、函数/方法

1.概述

在一个完整的项目中,某些功能可能会被反复使用,如果将反复出现的代码封装成函数,以后如果要继续使用该功能则直接使用函数即可,另外,如果要修改需求,只需要修改函数

本质:对某些特殊功能的封装

优点:

a.简化代码结构,提高应用的模块性

b.提高了代码的复用性

c.提高了代码维护性

# 需求:求圆的面积

# 1.
r1 = 45
area1 = 3.14 * r1 ** 2
print(area1)

r2 = 10
area2 = 3.14 * r2 ** 2
print(area2)

r3 = 5
area3 = 3.14 * r3 ** 2
print(area3)


# 2.优化
def area(r):
    return 3.14 * r ** 2

print(area(45))
print(area(10))
print(area(5))

2.定义

语法:

def  函数名(变量1,变量2....):

		函数体

	        return   返回值

说明:

a.def是一个关键字,是definition的缩写,专门定义函数

b.函数名:遵循合法标识符的规则和规范即可,尽量做到见名知意

c.(变量1,变量2....):被称为形式参数,是一个参数列表,都只是没有赋值的变量

d.函数体:封装某些特殊的功能

e.return是一个关键字,表示返回,只能用在函数中,表示结束函数,可以单独使用,也可以携带数据,当携带数据,则表示该函数的返回值

f.返回值:常量,变量,表达式

g.函数的定义分为两部分:函数的声明和函数的实现

h.变量1,变量2.... 和 return   返回值 可以根据具体的需求选择性的省略

"""
def  函数名(参数):
		函数体
	    return   返回值
"""

"""
注意:
    a.在实际项目开发中,一般情况下将不同的功能封装成不同的函数
    b.函数定义的过程,相当于将函数加载到内存中的过程,定义函数相当于定义变量,函数名相当于是一个变量名
    c.函数被定义之后,如果不使用【调用】,则不会执行其中的代码
"""

# print('start')

# 1.无参无返回值
def func1():
    print("11111")

# print('end')

# 2.有参无返回值
def func2(a):
    print("22222")

# 3.无参有返回值
def func3():
    print("33333")
    return  10

# 4.有参有返回值
def func4(a):
    print("444444")
    return  10


# 扩展
num = 10
print(type(num))     # <class 'int'>
print(type(func4))   # <class 'function'>

3.调用

def 函数名(形式参数):

函数体

调用函数的语法:函数名(实际参数)

形式参数:出现在函数的声明部分,简称形参,可以理解为是一个等待赋值的变量

实际参数:出现在函数的调用部分,简称实参,实参就是给形参赋值的数据

调用函数的过程实际上就是传参的过程

传参的过程:实参给形参赋值的过程,如果没有形参,则也没有实参

print('start')

# 1.直接调用
def func1():
    print("11111")
func1()

print('end')

def func2(a):
    print("22222",a)
func2(34)

def func3():
    print("33333")
    return  10
func3()

def func4(a):
    print("444444",a)
    return  10
func4('abc')

print("*" * 50)

# 2.相互调用
def show1():
    print("show~~~11111")
    show3()
def show2():
    print("show~~~22222")
def show3():
    show2()
    print("show~~~33333")

show1()

# 3.恶意调用,注意:避免出现下面函数调用的写法
# a
# def f1():
#     print("hello")
#     f1()
# f1()

# b
# def f1():
#     print("hello~~~~1111")
#     f2()
# def f2():
#     print("hello~~~2222")
#     f1()
# f1()

"""
注意:
    a.函数一旦被定义之后,需要手动调用,否则无法执行函数体
    b.在代码执行的过程中,一旦遇到函数的调用,则优先执行对应的函数体,当函数执行完毕,
      回到函数调用的位置,继续执行后面的代码 
    c.函数可以被直接调用,也可以函数之间相互调用,也可以将函数的调用应用在if语句或者运算表达式中
"""

4.参数

4.1基本使用

# 1.当封装一个函数的时候,是否需要设置参数
# 判断依据:查看需求中是否有未知项参与运算

# a.封装一个函数,求两个数的和
def add(num1,num2):
    total = num1 + num2
    print(total)

# b.封装一个函数,实现对数字列表的升序排序
def mysort(numlist):
    numlist.sort()
    print(numlist)

# 2.当调用函数的时候,实参给形参赋值需要注意的事项
add(34,67)
mysort([345,17,10])

# 3.
# a.必需参数
def func1(num1,num2):
    t = num1 + num2
    print(t)
func1(29,10)

# b.默认参数
def func2(num1,num2=0):
    t = num1 + num2
    print(t)
func2(29)
func2(29,10)

# c.关键字参数
def func3(num1,num2=0):
    print(num1,num2)
    t = num1 + num2
    print(t)
func3(num2=5,num1=76)

# d.不定长参数
# *x:x当成元组处理
def func41(*num):     # 打包
    print(num)    # 元组
    print(*num)   # 拆包
func41()
func41(34,56)
func41(23,5,7,8,9)

# **x:x当成字典处理
def func42(**num):     # 打包
    print(num)
func42()
func42(x=10,y=20)


"""
总结:
    a.实参和形参的数量需要匹配
    b.根据函数体的实现,实现和需求中使用的类型需要匹配
"""

4.2参数分类

参数分类:

  • 必需参数:常用
  • 默认参数
  • 关键字参数
  • 不定长参数【可变参数】
  • # 1.必需参数
    # a.注意1:必需参数传参的时候,一定要注意数量的匹配
    def func1():
        print("func~~~1111")
    func1()
    # func1(34)   # TypeError: func1() takes 0 positional arguments but 1 was given
    
    # b
    def func2(a):
        print("func~~~222",a)
    # func2()       # TypeError: func2() missing 1 required positional argument: 'a'
    func2(10)
    func2("abc")
    
    # c.注意2:必需参数传参的时候,一定要注意顺序的匹配
    def func3(name,age):
        print(f"姓名:{name},年龄:{age}")
    # func3(18,"jack")
    func3("jack",18)
    
    # d.注意3:必需参数传参的时候,一定要注意类型的匹配
    def func4(name,age):
        print("姓名:%s,年龄:%d" % (name,age))
    # func4("aaa","gahjg")  # TypeError: %d format: a number is required, not str
    func4("张三",10)
    
    print("*" * 30)
    
    
    # 2.默认参数
    # a.注意1:默认参数体现在形参上
    def test1(a,b = 0):   # a是一个必需参数,b是一个默认参数
        print(a,b,a + b)
    # 注意2:形参使用默认参数,如果实参给该参数未传参,则使用默认值
    test1(3)
    test1(3,5)    # 5会给b重新赋值
    
    
    # b.
    def test2(a = 0,b = 0,c = 0):
        print(a,b,c)
    test2()
    test2(2,6)
    test2(3,4,6)
    
    def test3(a,b = 0,c = 0):
        print(a,b,c)
    test3(6)
    
    def test4(a,b,c = 0):
        print(a,b,c)
    test4(6,3)
    
    # 注意3:如果形参有多个,可以必需参数和默认参数混合使用,但是在形参中,默认参数靠后书写
    # def test4(a,b = 0,c):   # SyntaxError: non-default argument follows default argument
    #     print(a,b,c)
    # test4(6,3)
    
    # 注意4:默认参数出现的意义就是为了简化函数的调用
    # end默认值为\n
    print(45)
    print(60)
    # print(34,end="*")
    
    
    # 3.关键字参数
    # 注意1:关键字参数体现在实参中
    def check1(name,age,score):
        print(f"姓名:{name},年龄:{age},成绩:{score}")
    # check1("jack",18,100)
    # check1(18,"jack",100)  # 逻辑不通,姓名:18,年龄:jack,成绩:100
    
    # 注意2:使用关键字参数传参可以不用匹配顺序,但是,关键字需要和形参的变量名保持一致
    check1(age=18,name="jack",score=100)  # 姓名:jack,年龄:18,成绩:100
    # check1(age=18,name1="jack",score=100)  # TypeError: check1() got an unexpected keyword argument 'name1'
    check1('aaa',score=88,age=10)
    check1("bbb",12,score=99)
    
    # 注意3:在实参中,关键字参数只能书写在参数的后面
    def check2(name,age,score):
        print(f"姓名:{name},年龄:{age},成绩:{score}")
    # check2(name="tom",10,66)  # SyntaxError: positional argument follows keyword argument
    # check2(10,66,name="tom")  # TypeError: check2() got multiple重复 values for argument 'name'
    
    # 注意4:默认参数和关键字参数可以结合使用
    def check3(name,age,score=0):
        print(f"姓名:{name},年龄:{age},成绩:{score}")
    check3("jack",10)
    check3("jack",10,67)
    check3(name="jack",age=10,score=67)
    check3("jack",age=10,score=67)
    check3("jack",10,score=67)
    
    print("*" * 30)
    
    
    # 4.不定长参数/可变参数:可以接受不定长的参数
    # a.*xxx,
    # 注意1:*xxx,xxx被当成一个元组处理
    def text1(*num):
        print(num)
    text1()
    text1(34)
    text1(34,56,67,68,7,8)
    text1(34,56,67,68,7,8,"abnfa",True)
    
    # 注意2:必需参数可以和不定长参数混合使用
    def text2(num1,*num2):
        print(num1,num2)
    text2(10,45,56,67,6,8,7,8)
    
    # 注意3:如果不定长参数出现在形参列表的前面,则可以结合关键字参数完成传参
    def text3(*num1,num2):
        print(num1,num2)
    # text3(10,45,56,67,6,8,7,8)  # TypeError: text3() missing 1 required keyword-only argument: 'num2'
    text3(10,45,56,67,6,8,7,num2 = 8)
    
    
    # 注意4:*xxx在形参列表中只能被使用一次
    # def text4(*num1,*num2):
    #     print(num1,num2)
    # text4(45,57,6,77,8)
    
    print("*" * 30)
    
    # b.**xxx
    # 注意1:**xxx,xxx会被当做字典处理
    def f1(**num):
        print(num)
    
    # 注意2:给**xxx的形参传参,则必须以key=value的方式传参
    f1(x=10,y=20,z=30)  # {'x': 10, 'y': 20, 'z': 30}
    
    # 注意3:**xxx在同一个函数的形参中只能出现一次
    # def f2(**num1,**num2):
    #     print(num1)
    # f2(x=10,y=20,z=30)
    
    # 注意4:*xxx和**xxx可以同时使用,但是,分别只能使用一次
    def f3(*num1,**num2):
        print(num1,num2)
    f3(45,45,65,7,67)
    f3(45,45,65,7,67,a=4,b=467,fag="abc")
    f3(a=4,b=467,fag="abc")
    
    # 注意5:一般情况下,如果*xx和**xxx结合使用,命名为:*args,**kwargs
    

4.3参数传递

"""
【面试题】值传递和引用传递的区别
值传递:传参的时候,传递的是不可变的数据类型,如:int float bool str tuple,当形参发生改变,对实参没有影响
引用传递:传参的时候,传递的是可变的数据类型,如:list dict set,当形参中的元素发生改变,实参会随着修改
"""

# 1.值传递
def func1(num):
    num = 100
    print(f"num={num}")

n = 66
func1(n)
print(f"n={n}")  # 66
"""
num=100
n=66
"""


# 2.引用传递
def func1(num):
    num[1] = 100   # 实参会随着修改
    # num = 100       # 实参不会随着修改
    print(f"num={num}")

n = [2,3,4]
func1(n)
print(f"n={n}")
"""
num=[2, 100, 4]
n=[2, 100, 4]
"""

二、函数基础【重点掌握】

1.返回值

return关键字的使用,注意:return只能使用在函数中

# 函数的返回值:函数执行完的结果,在哪里调用函数,就可以在哪里将返回值接出来

# 1.注意1:如果给函数未设置返回值,默认返回None
def func1():
    print('1111')
r1 = func1()   # 解释:r1 = func1函数的返回值
print(r1)   # None

# 2.注意2:return是一个关键字,可以单独使用,表示结束函数,
# 所以return后面的,和return平级的代码没有执行的机会,在和return平级的后面一般不书写代码
# a.
def func21(a,b):
    print('22222~~~1111')
    return          # return肯定会执行
    # print("over")   # 肯定不会执行,永远没有执行的机会
func21(4,2)

print('*' * 30)

# b
# 注意3:和return不平级的情况下,return后面的代码可能有执行的机会
def func22(a,b):
    print('22222~~~~2222')
    if a + b > 5:
        return      # return可能执行
    print("over")   # 有执行的机会
func22(4,2)

# c.
def func31():
    for i in range(3):   # 0 1 2
        for j in range(5):  # 0 1 2 3 4
            print(f"{i}={j}")
            if j == 2:
                break    # break结束当前循环
    print('over~~31')
func31()
"""
0=0
0=1
0=2
1=0
1=1
1=2
2=0
2=1
2=2
over~~31
"""

# 注意4:不管return书写在多少层嵌套循环中,只要执行到return,函数立马结束
def func32():
    for i in range(3):
        for j in range(5):
            print(f"{i}={j}")
            if j == 2:
                return
    print('over~~32')
func32()
"""
0=0
0=1
0=2
"""

# 3.return xxx
# 注意5:return xxx表示将指定的数据在函数执行完毕之后返回
# 返回值可以是常用,变量,表达式

# a
def func41():
    return "abc"
r41 = func41()
print(r41)

# b.
def func42(a):
    return a + 5
r42 = func42(34)
print(r42)

# c.
def func43(a,b):
    return a > b
r43 = func43(3,89)
print(r43)

# d.
def func44(a,b):
    return a,b    # 打包
r44 = func44(23,78)
print(r44)  # (23, 78)

# e.
def func45(a,b):
    if a > b:
        return a
    elif a < b:
        return b
    else:
        return "相等"
r45 = func45(56,56)
print(r45)

print("*" * 50)

# 4.return的意义
def func51():
    num1 = 66     # num1只能在函数内部使用
    print(num1)
func51()
# print(num1 + 5)  # NameError: name 'num1' is not defined

def func51():
    num1 = 66
    return  num1
r5 = func51()
print(r5 + 5)

# 举例
list1 = [34,65]
list1.append(10)
print(list1)

r = list1.pop()
print(r)

2.函数练习

如何封装函数:
    a.是否需要设置参数:需求中是否有未知项参与运算,有几个未知项参与运算
    b.是否需要设置返回值:函数体执行完毕之后是否有结果 或者 结果是否需要在函数的外面使用

# 1.封装一个函数,验证一个年是否是闰年
def isleapyear(year):
    # if year % 4 == 0 and  year % 100 != 0 or year % 400 == 0:
    #     return True
    # return False

    return year % 4 == 0 and  year % 100 != 0 or year % 400 == 0
r = isleapyear(2021)   # isdigit()
print(r)

# 2.封装一个函数 获取指定月的天数
def get_days(year,month):
    if month in [4,6,9,11]:
        return 30
    elif month in [1,3,5,7,8,10,12]:
        return 31
    else:
        if isleapyear(year):
            return 29
        return 28
r2 = get_days(2020,2)
print(r2)

# 9.模拟列表中sort的使用,对列表进行排序,默认升序,也可以降序
def mysort(numlist,reverse=False):
    if reverse:
        # 降序
        for i in range(len(numlist) - 1):
            for j in range(len(numlist) - 1 - i):
                if numlist[j] < numlist[j + 1]:
                    numlist[j],numlist[j + 1] = numlist[j + 1],numlist[j]
    else:
        # 升序
        for i in range(len(numlist) - 1):
            for j in range(len(numlist) - 1 - i):
                if numlist[j] > numlist[j + 1]:
                    numlist[j],numlist[j + 1] = numlist[j + 1],numlist[j]

list1 = [34,56,6,2,34,6]
mysort(list1)   # 升序
print(list1)

ist1 = [34,56,6,2,34,6]
mysort(list1,reverse=True)  # 降序
print(list1)

三、匿名函数【重点掌握】

概念:不再使用def这种标准形式定义函数,而是使用lambda表达式来创建函数,该函数没有函数名,被称为匿名函数

语法:lambda 形参列表:函数体

说明:

a.lambda只是一个表达式,用一行代码实现一个简单的逻辑,可以达到对函数的简化【优点】

b.lambda主体是一个表达式,而不是一个代码块,只能封装有限的逻辑【缺点】

c.lambda拥有自己的命名空间,不能访问自有列表之外或者全局命名空间里的参数

# 1.基本使用
# a.
def func1():
    print('11111')
func1()
print(func1)   # <function func1 at 0x103c9c1e0>
print(type(func1))  # <class 'function'>

# b.
# 语法:lambda  形参列表:函数体
# 方式一
func2 = lambda : print('2222')
print(func2)    # <function <lambda> at 0x1049916a8>
print(type(func2)) # <class 'function'>
# 调用匿名函数
func2()

# 方式二
(lambda : print('2222~~~~~'))()

"""
匿名函数的定义及调用

方式一:
    func2 = lambda : print('2222')
    func2()
方式二:
    (lambda : print('2222~~~~~'))()
"""

# 注意:不管是def定义的函数,还是lambda定义的匿名函数,函数定义完成之后,都需要手动调用

# 2.应用
# a.
def add1(num1,num2):
    return num1 + num2
r1 = add1(3,6)
print(r1)

# 注意:匿名函数中的返回值可以直接书写,不需要借助于return
add2 = lambda num1,num2: num1 + num2
r2 = add2(2,5)
print(r2)

# b.
def isleapyear1(year):
    if year % 4 == 0 and  year % 100 != 0 or year % 400 == 0:
        return '闰年'
    return '平年'
r1 = isleapyear1(2021)
print(r1)

isleapyear2 = lambda  year: '闰年' if year % 4 == 0 and  year % 100 != 0 or year % 400 == 0 else '平年'
r2 = isleapyear2(2020)
print(r2)

# c
iseven = lambda  num:True if num % 2 == 0 else False
r = iseven(34)
print(r)

# 3.注意事项
# 注意:匿名函数本质上仍然是一个函数,所以默认参数,关键字参数,不定长参数都可以使用
# a
f1 = lambda  a,b = 0:a + b
print(f1(4))
print(f1(4,2))

# b.
print(f1(a = 5))
print(f1(a = 5,b = 9))
print(f1(b = 6,a = 5))

# c
f1 = lambda  *num:sum(num)
print(f1(34,56,6,7,8))

# 4.使用场景
# 常用于其他函数的参数使用,如:sort(),常用高阶函数:sorted,map等

# 需求:列表按学生成绩从大到小排序
students = [
{'name': '小花', 'age': 19, 'score': 90, 'gender': '女', 'tel':
'15300022839'},
{'name': '明明', 'age': 20, 'score': 40, 'gender': '男', 'tel':
'15300022838'},
{'name': '华仔', 'age': 18, 'score': 90, 'gender': '女', 'tel':
'15300022839'},
{'name': '静静', 'age': 16, 'score': 90, 'gender': '不明', 'tel':
'15300022428'},
{'name': 'Tom', 'age': 17, 'score': 59, 'gender': '不明', 'tel':
'15300022839'},
{'name': 'Bob', 'age': 18, 'score': 90, 'gender': '男', 'tel':
'15300022839'}
]
"""
列表.sort()的工作原理
    a.如果列表元素是数字,底层是通过>或<进行数字比较的
    b.如果列表元素是字符串,底层是通过>或<进行ASCII码比较的
    c.但是,如果列表中的元素是字典等不支持>或<的数据,则需要自定义排序规则,格式:sort(key=排序函数)
    d.如果自定义排序规则,列表.sort(key=func)的工作原理:将列表中的元素依次传递给func的参数
      func的返回值将作为排序的依据【func的返回值必须要支持>或<的比较】
"""

# a.
# def func(subdict):
#     return subdict['score']
# students.sort(reverse=True,key=func)
# print(students)

# b.
students.sort(reverse=True,key=lambda subdict:subdict['score'])
print(students)


# 【思考题】/【面试题】
def func():
    l = []
    for i in range(5):
        l.append(lambda x:i * x)
    return l
r = func()
print(r[0](2))
print(r[1](2))
print(r[2](2))
print(r[3](2))
print(r[4](2))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值