1. 程式人生 > >python裝飾器學習筆記

python裝飾器學習筆記

LEGB:優先順序依次遞減

函式內部作用域,函式內部與內嵌函式之間,全域性作用域,內建作用域

passline=60

def func(val):
    passline=90
    if val>=passline:
        print('pass')
    else:
        print('field')
    def in_func():
        print('輸入了',val)
    in_func()

def Max(va1,va2):
    return max(va1,va2)

func(89)
print(Max(90,100))

閉包:內部函式中對enclosing(E)作用域的變數進行引用

def func_150(val):
    passline=90
    print('%x'%id(val))#會將變數新增到函式屬性中
    """5c8e78e0"""
    if val>=passline:
        print('%dpass'%val)
    else:
        print('field')
    # def in_func():
    #     print('輸入了',val)
    # in_func()
    # return in_func
'''(<cell at 0x00000285BAC1A648: int object at 0x000000005C8E78E0>,)'''
def func_100(val):
    passline=60
    print('%x'%id(val))
    if val>=passline:
        print('%dpass'%val)
    else:
        print('field')

def set_passline(passline):#passline=60
    def cmp(val):
        if val>=passline:
            print('Pass')
        else:
            print('fail')
    return cmp

# f=func(89)
# f()
# print(f.__closure__)
# func_100(89)
# func_150(89)

f_100=set_passline(60)
print(type(f_100))
print(f_100.__closure__)
'''<class 'function'>
(<cell at 0x000002C8B82AA648: int object at 0x000000005C8E7540>,)'''
f_100(89)
f_100(59)

#閉包可以實現封裝和程式碼複用

def my_sum(*arg):
    print('in my sum')
    # if len(arg)==0:
    #     return 0
    # for i in arg:
    #     if not isinstance(i,int):
    #         return 0
    return sum(arg)
def my_avg(*arg):
    print('in my_avg')
    # if len(arg)==0:
    #     return 0
    # for i in arg:
    #     if not isinstance(i,int):
    #         return 0
    return sum(arg)/len(arg)

def dec(func):#快取函式方法
    def in_dec(*arg):#My_sum會放到這個屬性中
        print('in dec arg=',arg)
        if len(arg) == 0:
            return 0
        for i in arg:
            if not isinstance(i, int):
                return 0
        return func(*arg)#呼叫函式方法
    return in_dec
#my_sum = in_dec(*arg)
#先呼叫dec 返回in_dec --->my_sum
#第二步賦值 my_sum發生變化,本質上等於in_dec
my_sum=dec(my_sum)
my_avg=dec(my_avg)
'''呼叫dec,my_sum傳入,再使用內嵌函式'''
'''實際上呼叫的函式等於內嵌函式'''
print(my_sum(1,2,3,4))
print(my_avg(1,2,3,4))

裝飾器用來裝飾物件,語法糖,返回一個函式物件

def dec(func):#快取函式方法
    print('call dec')
    def in_dec(*arg):#My_sum會放到這個屬性中
        print('in dec arg=',arg)
        if len(arg) == 0:
            return 0
        for i in arg:
            if not isinstance(i, int):
                return 0
        return func(*arg)#呼叫函式方法
    print('return in_dec')
    return in_dec#返回閉包
#其實就是條件過濾器
@dec#-->返回一個函式物件,就是閉包
def my_sum(*arg):
    print('in my sum')
    # if len(arg)==0:
    #     return 0
    # for i in arg:
    #     if not isinstance(i,int):
    #         return 0
    return sum(arg)

 

def deco(func):
    print('in deco')
    def bar(x,y):
        '''實際上是SSum'''
        print(bar.__closure__)
        print('in bar')
        func(x,y)
    return bar

#
@deco
def SSum(x,y):
    print(SSum.__closure__)
    print('加法:',x+y)

SSum(1,2)

in deco
(<cell at 0x0000015462C7A648: function object at 0x000001546318D510>, <cell at 0x0000015462C7A9A8: function object at 0x000001546318D488>)
in bar
(<cell at 0x0000015462C7A648: function object at 0x000001546318D510>, <cell at 0x0000015462C7A9A8: function object at 0x000001546318D488>)
加法: 3