12、函数

目录

一、定义

二、传入不定长参数

        1、接收到的是一个元组

        2、接受到的是一个字典

        3、参数装包拆包

        4、缺省参数

        5、python中参数传递都是引用传递

三、返回值

四、函数使用

1、函数功能

2、参数

3、返回值

4、help(函数)

五、函数高级用法

1、偏函数

2、高阶函数

3、返回函数

4、匿名函数

5、闭包

6、装饰器

7、生成器

8、递归函数

9、作用域


一、定义

        1、方便代码重用,分解任务简化程序逻辑,使代码更加模块化。

        2、内建函数、三方函数、自定义函数

二、传入不定长参数

        1、接收到的是一个元组

        def func(*ele):
            print(ele, type(ele))=>(1, 2) <class 'tuple'>
        func(1, 2)

        2、接受到的是一个字典

        def func(**ele):
            print(ele, type(ele))=>{'das': '1', 'sadasd': '2'} <class 'dict'>
        func(das="1", sadasd="2")

        3、参数装包拆包

        def func(*ele):
            print(ele)=>(1, 2, 3)装包
            print(*ele)=>1 2 3拆包
        func(1, 2, 3)

        但对字典的解包调用{'a': '1', 'b': '2'},func(**dict)传入参数为a='1',b='2',故要注意参数名称是否对应。133-Python函数-参数-不定长参数-参数的拆包和装包_哔哩哔哩_bilibili

        4、缺省参数,写函数形参时将其=“默认值”

        5、python中参数传递都是引用传递(传地址),对于可变数据类型,改变的是同一地址空间的值,对于不可变数据类型,改变参数会开辟一块新的空间。

三、返回值

1、return 参数

2、返回多个参数时,返回参数使用列表、元组或字典等。

四、函数使用:写注释,在函数体前写三引号注释。

1、函数功能

2、参数:

        含义、类型、是否可省略、默认值

3、返回值:

        含义、类型

4、可以用help(函数)进行查询功能

五、函数高级用法

1、偏函数

        用新偏函数指明某个函数里面一个参数偏爱某个值,方便的处理各种默认情况。

        def func(a, b, c=1):
        newFunc = functools.partial(func, b=2)

2、高阶函数

        把一个函数当作参数传给另一个函数,eg:

        def getKey(x):
                return x[1]
        stu = [("std2", 18), ("std1", 20), ("std3", 16)]
        resu1=sorted(stu, key=getKey)
        print(resu1)=>[('std3', 16), ('std2', 18), ('std1', 20)]

3、返回函数

        一个函数内部,它返回值是另一个函数,eg:

def getfunct(str):
    def sum(a, b, c):
        print(a + b + c)
    def dedu(a, b, c):
        print(a - b - c)
    if str == "+":
        return sum
    elif str == "-":
        return dedu

4、匿名函数

lambda 参数1,参数2 : 表达式

        (1)名称:无(匿名),参数:给了,返回值:表达式的值

        (2)使用:上述getkey()函数可以替换掉了,比如sort中key=lambda x:x["name"]

5、闭包

        (1)前提函数嵌套

        (2)内层函数引用了外层函数的参数或传进外层的参数

        (3)外层函数将内层函数作为返回值返回

        (4)闭包指内层函数和引用外层函数的整体

eg:

def test():
    a = 1
    def test2():
        print(a)
    return test2

        (5)在内部函数修改外部变量的时候需要使用nolocal进行声明是修改外部的函数而不是定义内部函数的新参数

        (6)函数执行时才会查找函数的内部标识,所以下面列子,结果为2

        def test():
            a = 1
            def test2():
                print(a)
            a = 2
            return test2
        newFunct = test()
        newFunct()==>2

6、装饰器

        (1)将业务逻辑和功能函数分离:逻辑更加清楚、便于维护、提升代码重用

        (2)增加功能:修改业务逻辑最繁琐复杂<修改功能函数也可能很多<增加新的函数定义在功能函数中调用最好

        (3)上述最后一种方法违背了单一功能原则,即功能函数内部功能不纯粹

        (4)面向对象、过程编程的开放封闭原则;

                封闭:写好的代码尽可能不要修改

                开放:欲增加新的功能,在原代码的基础上单独进行拓展

        (5)装饰器:在不改变函数名及函数体的情况下,给函数增加额外功能(用上述闭包)

        eg:使用语法糖方式

        def test(func):
            def inner():        #ftp = inner()
                print("happy")
                func()        # func==ftp
            return inner
        @test   # == ftp=test(ftp)
        def ftp():
            print("sad")
        ftp()==>happy\nsad

        (6)装饰器是立即执行,执行到@test时候就已经执行了

        (7)装饰器的叠加:装饰器从上到下去装饰,从下到上去执行,eg:

        @test_star  # == ftp=test_star(ftp)
        @test_line  # == ftp=test_line(ftp)
        def ftp():
            print("sad")=>***************\n--------------\nsad

        (8)对不定长参数的装饰,可使用元组及字典*args、**kwargs,在装饰器内部func函数应该传入解包的参数,即func(*args,**kwargs)才能返回原来函数执行

        (9)装饰有返回值的函数,需要inner中return返回func()的值

        (10)有参数的装饰器,根据参数不同生成不同的装饰器

        def getTest(char):        #获取一个装饰器
            def test(func):        #装饰器本身
                def inner():
                    print(char * 30)
                    func()
                return inner
            return test
        @getTest("-")        #用传入了参数的装饰器对下面函数进行装饰

7、生成器

        (1)特殊的迭代器,但迭代器的抽象层级更高,生成器拥有迭代器的一些特性

        (2)迭代器特性:

                惰性计算数据节省内存;

                能够记录状态,通过next()函数访问下一个状态

                具备可迭代特性  for in

        (3)创建

                a、将列表生成式的[]改为()即可

                b、函数中包含yield语句就会定义出一个生成器,使用next()可以是这个函数执行在yield处中断

def test():
    print("ddd")
    yield 1
    print("a")
    yield 2
    print("b")
    print("c")
    yield 3
    print("----")
g = test()
print(g)        #<generator object test at 0x00000176FADBDCF0>
print(next(g))        #ddd\n1
print("***")
print(next(g))        #a\n2
print("***")
print(next(g))        #b\nc\n3
print("***")

        (4)send方法:跟next()作用差不多,但是可以给上一次挂起的yield语句指定返回值(原本是没有返回值的),但第一次使用时必须t.send(None),因为找不到上一次挂起的yield

        (5)g.close()使用此函数后,若继续调用next(),会出现停止迭代的异常提示

        (6)注意:遇到return会马上抛出异常,且return的值会写在异常提示中;生成器也不能多次迭代 。

8、递归函数 (一种函数调用方式):传递+回归,没啥写的

9、作用域

        (1)变量的作用域(静态):因为位置的不同而有不同的作用域

        (2)命名空间(LEGB):

                L-Local函数内命名空间:整个函数体范围

                E-Encloseing function locals外部嵌套函数的命名空间:闭包函数

                G-Global全局命名空间:当前模块、文件

                B-Buitin内建模块命名空间:所有模块、文件,eg:print、__name__

        (3)python中不存在块级作用域,块比如for、if

        (4)nolocal a声明,nolocal语句仅适用于闭包改变外层变量值;global a声明用于改变函数中的全局变量

        (5)查询局部变量的函数locals();查询全部变量的函数glocals(),包括系统自带的

        (6)访问原则:从内到外

        (7)定义规范:全局变量在文件最上面

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值