python作用域,闭包,装饰器

"""
了解装饰器之前,学习路线
python函数的作用域
python的闭包
装饰器
"""

python函数的作用域

LEGB
L:local函数内部作用域 #函数内部的
E:enclosing 函数内部与内嵌函数之间 #函数外面还有一层函数,外层函数的变量
G:global 全局作用域  # 全局变量
B:build-in 内置作用域 #python内置的方法,无需导入的那种
L>E>G>B
查找顺序从左到右

python闭包

"""
闭包的概念
首先了解了LEGB各自的作用域
闭包其实就是 一个函数,对E中的变量进行了引用,这个函数就称之为闭包
"""
"""
函数 实质或者特点属性:
函数是一个对象,内存中会有一个存储空间
函数在执行完毕只有,会回收所有的内部函数
函数属性
函数有返回值
"""

def func(val):
    print("%x"%id(val))
    if val <0:
        print("-")
    elif val >=0:
        print("+")
    else:
        print("~~~~~~")
    def out_put(): # 会把val 添加到out_put函数属性中去
        print(val)
    out_put()
    return out_put
f = func(88)
f()# out_put 没有被回收,被f引用了。
print(f.__closure__) # 函数属性
"""
5f7678c0
+
88
88
(<cell at 0x0000025ECB6C84F8: int object at 0x000000005F7678C0>,)

注意
5f7678c0,(<cell at 0x0000025ECB6C84F8: int object at 0x000000005F7678C0>,)

"""

闭包的简单应用

def func_150(val)"""
考试150分满分,90分及格。
"""
	passline = 90
    if val >= passline:
        print("pass")
    else:
        print("failed")
    
def func_100(val)"""
考试100分满分,60分及格。
"""
	passline = 60
    if val >= passline:
        print("pass")
    else:
        print("failed")

"""
这个时候,如果打印的pass要变,就会修改两处(两个函数都需要分别修改),很麻烦

使用闭包可以解决这个问题
"""

def set_passline(passline):
    def cmp(val): # 2.cmp函数,有一个passline的属性
        if val >= passline: #1.引用了passline 
            print("pass++")
        else:
            print("failed--")
    return cmp #3.返回了cmp函数

f_60 = set_passline(60) #4.f_60接收了cmp函数
f_60(80)

f_90 = set_passline(90)# 设置及格线为90
f_90(80)

"""
这样,想要修改输出信息,只需要修改一次即可
"""

闭包的作用

"""封装与代码的复用"""

def my_sum(*arg):#求和
    return sum(arg)
def my_average(*arg):# 求平均值
    return sum(arg)/len(arg)
"""
注意,如果不判断参数类型,运行时候可能会报错的
所以我们需要判断检测参数类型
两个函数,又需要写两遍
现在使用闭包的思想
"""

def dec(func):
    #1. func 是dec的局部变量,是in_dec的 E 作用域
    def in_dec(*arg):#3 my_sum 引人,变为in_dec函数属性
        if len(arg)==0:
            return 0
        for val in arg:
            if not isinstance(val,int):
                return 0
        return func(*arg) #2 引用了func
    return in_dec #4 返回了 in_dec

my_sum = dec(my_sum)
print(my_sum(1,2,3,4,5,6))

python装饰器

"""
装饰器 用来装饰函数
返回一个函数对象
被装饰函数标识符 指向返回函数对象
语法糖 @deco
"""

"""
上面闭包 中 代码
my_sum = dec(my_sum)
装饰器其实就是对闭包的使用

def dec:...
	pass
	#略

@dec
def my_sum(*arg):# my_sum = in_dec,装饰器的作用
    return sum(arg)
    
# @dec 和 my_sum = dec(my_sum) 作用是一样的
"""


# 简单的装饰器
def debug(func):
    def wrapper(*args, **kwargs):  # 指定宇宙无敌参数
        print "[DEBUG]: enter {}()".format(func.__name__)
        print 'Prepare and say...',
        return func(*args, **kwargs)
    return wrapper  # 返回

@debug
def say(something):
    print "hello {}!".format(something)
    
    
# 基于类的装饰器
class logging(object):
    def __init__(self, level='INFO'):
        self.level = level
        
    def __call__(self, func): # 接受函数
        def wrapper(*args, **kwargs):
            print "[{level}]: enter function {func}()".format(
                level=self.level,
                func=func.__name__)
            func(*args, **kwargs)
        return wrapper  #返回函数

@logging(level='INFO')
def say(something):
    print "say {}!".format(something)
    
    
"""
https://www.imooc.com/video/10835
https://www.cnblogs.com/cicaday/p/python-decorator.html
"""

猜你喜欢

转载自blog.csdn.net/sunt2018/article/details/85989249
今日推荐