zoukankan      html  css  js  c++  java
  • python基础语法_9-1闭包 装饰器补充

    1、闭包的概念
    closure:内部函数中对enclosing作用域的变量进行引用,外部函数返回内部函数名
     
    2、函数实质与属性
    函数是一个对象:在内存中有一个存储空间
    函数执行完成后内部变量回收:引用计数不为零
    函数属性:特殊属性
    函数返回值
    例子
    passline = 60
    def func(val):
    print('%x' % id(val)) # 查看变量名地址
    if val >= passline:
    print('pass')
    else:
    print('failed')
    def in_func(): # (val,)添加后是元组类型不能变的
    print(val) # 引用变量后说明变量添加到内函数属性中,使用时直接在内函数中查找
    in_func()
    return in_func
    # func(88)
    a =func(88) # 将变量名指向in_func
    print(a.__name__) # 查看变量名
    a() #实际是调用了in_func(),相当于a和in_func指向同一个函数,a和in_func只是函数名
    print(a) #查看in_func()在func函数属性中的地址
    print(a.__closure__) # 查看in_func()中的属性是否存在val变量,闭包属性
    3、闭包的作用和优点
    • 实现了函数封装
    • 提高代码的复用
     
    4、将代码的公共部分抽出,用闭包的形式代替抽出部分,将要使用的函数当作参数
    例子:
    两个代码重复的方法:
    def my_sum(*arg):
    if len(arg) == 0: # 被除数不能为0
    return 0
    for val in arg: # 数据只能是int型
    if not isinstance(val,int):
    return 0
    return sum(arg)
    def my_average(*arg):
    if len(arg) == 0:
    return 0
    for val in arg:
    if not isinstance(val,int):
    return 0
    return sum(arg)//len(arg)
     
    print(my_sum(1,2,3,'2'))
    print(my_average())
    重构后:
    def my_sum(*arg):
    return sum(arg)
    def my_average(*arg):
    return sum(arg)//len(arg)
    def dec(func):
    def in_dec(*arg):
    if len(arg) == 0: # 被除数不能为0
    return 0
    for val in arg: # 数据只能是int型
    if not isinstance(val,int):
    return 0
    return func(*arg)
    return in_dec
    my_sum = dec(my_sum) # 1、先调用dec,2、再将my_sum函数名指向函数in_dec
    my_average = dec(my_average)
     
    # 当使用my_sum函数时,3、调用in_dec,4、再调用my_sum
    print(my_sum(1,2,3,'2'))
    print(my_average())
     
    5、装饰器:
     
    • 装饰器用来装饰函数
    • 返回一个函数对象
    • 被装饰函数标识符指向返回的函数对象
    • 语法:@deco
    装饰器实质是对闭包的使用
    def dec(func):
    print('1、call dec')
    def in_dec(*arg):
    print('3、call in_dec')
    if len(arg) == 0:
    return 0
    for val in arg:
    if not isinstance(val,int):
    return 0
    return func(*arg)
    print('2、return in_dec')
    return in_dec
    print('装饰器代码执行顺序:')
    @dec # 等于my_sum = dec(my_sum)这句话
    def my_sum(*arg): # 装饰过后my_sum名指向in_dec函数对象,此时in_dec会调用原来的my_sum,要使用my_sum(1,2)才能调用
    print('4、call my_sum')
    return sum(arg)
    # print(sum(arg))
    def average(*arg):
    return sum(arg)//len(arg)
     
    print('调用被修饰的函数后才会执行闭包中的函数')
    print(my_sum(1,2,3))
    输出结果:
    装饰器代码执行顺序:
    1、call dec
    2、return in_dec
    调用被修饰的函数后才会执行闭包中的函数
    3、call in_dec
    4、call my_sum
  • 相关阅读:
    ModelSim中Altera仿真库的添加
    0欧电阻之作用
    Modelsim之时序仿真
    FPGA之常见错误
    【转】VCC、VDD、VEE、VSS应用
    FROM 子句一个或多个派生表
    asp.net笔记
    GridView分页,个人认为比较简单的。
    GridView中模拟RadioButton组代码
    SPSWC:SearchBoxEx控件
  • 原文地址:https://www.cnblogs.com/TomBombadil/p/10979397.html
Copyright © 2011-2022 走看看