python 笔记:函数

空函数

如果想定义一个啥都不做的空函数,可以用pass语句

因为python没有;,所以if语句如果没有内容的话,用pass语句

2 函数的返回值

函数可以返回多个值(相当于返回一个tuple——)

3 函数的形参

3.1 默认值

对于函数形参,可以自动设置默认值(默认参数要在最后面)

3.2 可变参数

以一个*开头的就是可变参数

可变参数在函数定义中不能出现在特定参数默认参数前面,因为可变参数会吞噬掉这些参数。

调用函数 report('Mike', 8, 9),输出的结果为 Mike total grade is 17

调用函数 report('Mike', 8, 9, 10),输出的结果为 Mike total grade is 27

3.3 关键字参数

以两个*开头的参数就是关键字参数

关键字参数可以传入0个或者任意个含参数名的参数,这些参数名在函数定义中并没有出现,这些参数在函数内部自动封装成一个字典(dict).

通过可变参数和关键字参数,任何函数都可以用 universal_func(*args, **kw) 表达。

4 global

Python中定义函数时,若想在函数内部对函数外的变量进行操作,就需要在函数内部声明其为global。

不加global这个修饰词的时候,作用域仅仅为func()的内部,加了之后,作用域为全局

                 VS                      

           VS                     

如果局部要对全局变量修改,而不使用global关键字,那么会报错

如果局部不声明全局变量,并且不修改全局变量,则可以正常使用

5 nonlocal

nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。

5.1 LEGB 顺序

  • 对于函数中使用的变量名,python 依次搜索以下4个作用域:
    • 本地作用域(L,即当前函数对应的作用域)
    • 上层结构的作用域(E,即嵌套函数中上层函数对应的作用域,eg nonlocal)
    • 全局作用域(G,即当前模块的作用域 eg global)
    • 内置作用域(B,python预定义的__builtin__模块对应的,可以用 dir(__built__) 查看)
  •  python在第一个能够找到这个变量名的地方停下来
  • 如果变量名在上面这4个地方都没找到,就会报错
def scope_test():
    def do_local():
        spam = "局部变量"  
    def do_nonlocal():
        nonlocal spam  
        # 使用外层的spam变量
        spam = "nonlocal 变量"  
    def do_global():
        global spam
        spam = "global 变量"  
    spam = "test spam" 
    do_local()
    print("本地分配后:", spam) 
    #do_local中的spam是那个函数中的本地spam,不会传到scope_test这一上层结构的作用域中
    do_nonlocal()
    print("nonlocal分配后:", spam) 
    #nonlocal的spam
    do_global()
    print("global分配后:", spam) 
    #找spam时,nonlocal作用域的spam先于global的spam,故而输出是:nonlocal 变量
scope_test()
print("全局范围:", spam)
#此时没有nonlocal变量对应的作用域了

'''
本地分配后: test spam
nonlocal分配后: nonlocal 变量
global分配后: nonlocal 变量
全局范围: global 变量
'''

6 yield

带yield的函数是一个生成器,而不是一个函数了。

这个生成器有一个函数就是next函数,next就相当于“下一步”生成哪个数。

这一次的next开始的地方是接着上一次的next停止的地方执行的,所以调用next的时候,生成器并不会从foo函数的开始执行,只是接着上一步停止的地方开始,然后遇到yield后,return出要生成的数,此步就结束。

输出如下:

解释:

1.程序开始执行以后,因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)

2.直到调用next方法时,foo函数正式开始执行,先执行foo函数中的print方法,然后进入while循环

3.程序遇到yield关键字,把yield想象成return,return了一个4之后,程序停止。并没有执行赋值给res操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面一行的print的结果,第二个是‘return’出的结果)是执行print(next(g))的结果。

4.程序执行print("*"*20),输出20个*

5.又开始执行下面的print(next(g)),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行res的赋值操作,这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候res赋值是None,所以接着下面的输出就是res:None,

6.程序会继续在while里执行,又一次碰到yield,这个时候同样return 出4,然后程序停止,print函数输出的4就是这次‘return’出的4.

7 Lambda函数

lambda函数包含的表达式不能超过

lambda函数的格式:冒号前面的是参数,可以有多个,有逗号隔开来,冒号右边的是表达式

函数名 = lambda 参数列表 : 表达式

lambda函数的返回值是一个函数的地址(函数对象) 

7.1 lambda 函数应用场景

filter,map,reduce,列表的sort等等

7.1.1 sort

 7.1.2 map

7.1.3 filter

8 嵌套函数

def inc(x):
    return x+1

def dec(x):
    return x-1

def make_operation(func):
    def operate(x):
        return func(x)
    return operate

add_operation=make_operation(inc)
print(add_operation(1))
#2
'''
add_operation(1)相当于make_operation(inc)(1)

make_operation(inc)相当于 inc

make_operation(inc)(1)就是inc(1)
'''

minus_operation=make_operation(dec)
print(minus_operation(1))
#1
'''
minus_operation(1)相当于make_operation(dec)(1)

make_operation(dec)相当于 dec

make_operation(dec)(1)就是dec(1)
'''

9 函数装饰器(@的使用方法)

9.1 单个@

def make_pretty(func):
    def inner():
        print('decorate ...',end='')
        func()
    return inner

def ordinary():
    print('ordinary function')
    
ordinary()
#ordinary function



@make_pretty
def ordinary1():
    print('ordinary function')
    
ordinary1()
#decorate ...ordinary function

'''
等价于下面的写法
'''
make_pretty(ordinary)()
#decorate ...ordinary function

9.2 带参数的函数装饰器

9.2.1 固定个数的参数

def make_pretty(func):
    def inner(msg):
        print('decorate ...',end='')
        func(msg)
    return inner


@make_pretty
def ordinary1(msg):
    print(msg)
    
ordinary1('message')
#decorate ...message

'''
(make_pretty(ordinary1))('message')
——>
(inner(ordinary1)){'message')
——>decorate ...message
'''

9.2.2 多个参数(参数个数不定)

用 *args 和 **kwargs 作为装饰器内部嵌套函数的参数,*args 和 **kwargs 表示接受任意数量和类型的参数

def make_pretty(func):
    def inner(*args,**kwargs):
        print('decorate ...',end='')
        func(*args,**kwargs)
    return inner


@make_pretty
def ordinary1(msg):
    print(msg)
    
ordinary1('message')
# decorate ...message


@make_pretty
def ordinary2(a,b):
    print(a,b)
    
ordinary2('1','2')
# decorate ...1 2

9.3 嵌套函数装饰器

def star(func):
    def innner(*args,**kwargs):
        print('*'*30)
        func(*args,**kwargs)
        print('*'*30)
    return innner

def persent(func):
    def innner(*args,**kwargs):
        print('%'*30)
        func(*args,**kwargs)
        print('%'*30)
    return innner

@star
@persent
def printer3(msg):
    print(msg)
printer3('printer3')
'''
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
printer3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
'''

'''
相当于是star(persent(printer3))

star函数做的事情是:
print('*'*30)
persent(printer3)
print('*'*30)

persent(printer3)做的事情是
print('%'*30)
printer3
print('%'*30)

所以合在一块就是:
print('*'*30)
print('%'*30)
printer3
print('%'*30)
print('*'*30)
'''

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UQI-LIUWJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值