016-Python函数补充

本文详细介绍了Python中的闭包、装饰器和生成器的概念及用法。通过实例解析了闭包如何在函数嵌套中引用外部变量,装饰器如何在不改变原函数代码的基础上增加功能,以及生成器如何实现惰性计算和高效内存管理。同时,探讨了装饰器的参数化和生成器的send()方法,展示了这些高级特性在实际编程中的应用。
摘要由CSDN通过智能技术生成

话不多说,上代码,看结果。

print('#########################9、闭包##################################')
# 在函数嵌套的前提下   内层函数引用了外层函数的变量(包括参数)
# 外层函数又把内层函数当做返回值进行返回
# 这个内层函数+所引用的外层变量, 称为 "闭包"

# 外层函数, 根据不同的参数, 来生成不同作用功能的函数


def fun3(x):
    def fun4(y):
        return x * y
    return fun4


a = fun3(2)
b = a(5)
print(a)
print(b)
print(fun3(2)(5))

# 闭包中要修改引用的外层变量  需要使用nonlocal 变量声明
# 否则当做是闭包内, 新定义的变量
print('#############')


def fun5(x):
    x = x

    def fun6(y):
        nonlocal x
        x += 1
        return x * y
    return fun6


a = fun5(2)
b = a(5)
print(a)
print(b)
print(fun5(2)(5))


print('#########################10、装饰器##################################')
# 在函数名以及函数体不改变的前提下, 给一个函数附加一些额外代码
# 要装饰的函数无参数
# def fun7():
#     print('fun7')
#
# fun7()

# 现在想在输出的fun7上面加print('##########')


def fun8(func):
    def inner():
        print('#######')
        func()
    return inner


@fun8       # fun7 = fun8(fun7)
def fun7():
    print('fun7')


fun7()

# 要装饰的函数有参数
# 无论什么场景, 保证函数调用参数个数一致
# 为了通用, 可以使用不定长参数, 结合 拆包操作进行处理


def fun10(func):
    def inner(*args, **kwargs):
        print('@@@@@@')
        func(*args, **kwargs)
    return inner


@fun10  # fun9 = fun10(fun9)
def fun9(num, num2, num3):
    print(num, num2, num3)


fun9(12, 13, num3=14)


# 对有返回值的函数进行装饰   无论什么场景, 保证函数返回值一致

def fun10(func):
    def inner(*args, **kwargs):
        print('^^^^^^^^^^^^^^^^^^^^^')
        ret = func(*args, **kwargs)
        return ret
    return inner


@fun10   # fun9 = fun10(fun9)
def fun9(num, num2=13, num3=14):
    print(num, num3)
    return num, num3


fun9(12, num3=145)

# 带有参数的装饰器
# 通过@装饰器(参数)的方式, 调用这个函数, 并传递参数; 并把返回值, 再次当做装饰器进行使用
# 先计算 @ 后面的内容, 把这个内容当做是装饰器


# 在fun9输出上面打一行自己想要的符号

def fun11(char):
    def fun10(func):
        def inner(*args, **kwargs):
            print(char * 10)
            ret = func(*args, **kwargs)
            return ret
        return inner
    return fun10


@fun11("~")   # fun9 = fun10(fun9)
def fun9(num, num2=13, num3=14):
    print(num, num3)
    return num, num3


fun9(12, num3=145)


print('#########################11、生成器##################################')
# 是一个特殊的迭代器(迭代器的抽象层级更高)
# 生成器表达式
# 把列表推导式的[]修改成()
l = (i for i in (1, 2, 3) if i < 10)
print(next(l))
print(next(l))
print(l.__next__())
# print(l.__next__())  # StopIteration

print('1、#######')
# yield 语句
# yield可以去阻断当前的函数执行
# 再使用next()函数或__next__()都会让函数继续执行
# 当执行到下一个 yield语句的时候,又会被暂停

def fun12():
    yield 1
    print('a')
    yield 2
    print('b')
    yield 3
    print('c')


f = fun12()
print(f.__next__())
print(next(f))
print(next(f))
# print(next(f))  # StopIteration


# send() 方法
# send方法有一个参数,指定的是上一次被挂起的yield语句的返回值
# 相比于.__next__()   可以额外的给yield 语句 传值
# 注意第一次调用   t.send(None)
print('2、#######')


def fun12():
    yield1 = yield 1
    print(yield1)
    print('a')
    yield2 = yield 2
    print(yield2)
    print('b')
    yield3 = yield 3
    print(yield3)
    print('c')


g = fun12()
print(g.send(None))
print('!!!')
print(g.send(123))
print('!!!')
print(next(g))
print('!!!')
# print(g.send(234))    #  print(g.send(234))

# 关闭生成器
# g.close() 后续如果继续调用, 会抛出StopIteration异常提示
print('3、#######')
def fun13():
    yield 1
    print('a')
    yield 2
    print('b')
    yield 3
    print('c')


g = fun13()
print(next(g))
g.close()
# print(g.send(234))  # StopIteration

# 如果碰到return会直接终止, 抛出StopIteration异常提示

print('4、#######')


def fun14():
    yield 1
    print('a')
    yield 2
    print('b')
    return 123
    yield 3
    print('c')


g = fun14()
print(next(g))
print(next(g))
# print(next(g))  # StopIteration: 123

# 生成器只会遍历一次!!!!!!!!!!!!!!!!!!!!
print('#########################13、函数作用域##################################')
# 1、基本概念
# (1)变量的作用域
#      变量的作用范围   可操作范围
# 	    Python是静态作用域,也就是说在Python中,变量的作用域源于它在代码中的位置,在不同的位置, 可能有不同的命名空间
# (2)命名空间
# 	    是作用域的体现形式
#       不同的具体的操作范围
# (3)Python-LEGB
# 		L-Local 函数内的命名空间  作用范围: 当前整个函数体范围
# 		E-Enclosing function locals  外部嵌套函数的命名空间  作用范围: 闭包函数
# 		G-Global  全局命名空间  作用范围: 当前模块(文件)
# 		B-Builtin 内建模块命名空间   作用范围: 所有模块(文件)
#   注意   Python中没有块级作用域  块级作用域   代码块中, 比如 if while for 后的代码块
# 		LEGB规则   按照L -> E -> G -> B 的顺序进行查找
# 2、基于命名空间的常见变量类型
# 	(1)局部变量
# 		在一个函数内部定义的变量;
# 		作用域为函数内部
# 		查看局部变量   locals()
# 	(2)全局变量
#       在函数外部, 文件最外层定义的变量
# 		作用域为整个文件内部
#       查看全局变量   globals()
# 3、注意点
# 	访问原则   从内到外
# 	结构规范  全局变量 ->函数定义(使用、修改) ->后续代码
# 	全局变量和局部变量重名
# 		获取  就近原则
# 		修改   global 全局变量声明
# 			    l -> e  unlocal
# 	命名  全局变量  g_xxx

结果如下图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
就先这样,遇到别的再补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值