天天看點

python 函數進階功能

閉包

我們可以将閉包了解為一種特殊的函數,這種函數由兩個函數的嵌套組成,且稱之為外函數和内函數,外函數傳回值是内函數的引用,此時就構成了閉包。

# 閉包
# 外部函數的參數被内部函數引用,内部函數對外部參數的參數進行處理,傳回一個結果,外部函數傳回内部函數(引用内部函數)
def a_func(n):
    def b_func(m):
       return n*m
    return b_func # 注意是沒有(),不是b_func()
    # 外函數傳回内函數的引用,這裡的引用指的是内函數b_func在記憶體中的起始位址

a=a_func(3)
print(a(4))
print(a(10))      

裝飾器

裝飾函數,增加被裝飾函數的功能

裝飾器不帶參數,被裝飾參數不帶參數

import time

# 定義裝飾函數

def timer(func):
    # 統計執行時間
    def wrapper():
        start_time=time.time()
        func()
        stop_time=time.time()
        print('運作的時間 %s' %(stop_time-start_time))
    return wrapper

# 定義被裝飾函數
@timer
def i_can_sleep():
    time.sleep(3)

# 調用i_can-sleep方法
i_can_sleep()

# 執行順序,首先将i_can_sleep()傳給timer,也就是timer(i_can_sleep());
# 然後執行wrapper()函數

# 裝飾器與閉包的不同點,裝飾函數傳入的參數是一個函數,閉包傳入的參數      

被裝飾函數帶參數

# 被裝飾函數帶參數,也就是裝飾函數的外部函數帶參數
# 發現需要先定義裝飾函數
def tips(func):
    def nei(a,b):  # 裝飾函數的内部函數需要接收被裝飾函數的參數
        print('start')
        func(a,b)
        print('end')
    return nei

@tips
def sum(a,b):
    print(a+b)

a=sum(8,9)      

裝飾器帶參數

ef new_tips(args):
    def tips(func):
        def nei(a,b):  # 裝飾函數的内部函數需要接收被裝飾函數的參數
            print('start to %s' % args)
            func(a,b)
            print('end to %s' % args)
        return nei
    return tips

@new_tips('add')
def sum(a,b):
    print(a+b)

a=sum(8,9)      

還可以擷取被裝飾函數的一些資訊

def new_tips(args):
    def tips(func):
        def nei(a,b):  # 裝飾函數内部函數需要接收被裝飾函數的參數
            print('func %s start to %s' % (func.__name__,args))
            func(a,b)
            print('func %s end to %s' % (func.__name__,args))
        return nei
    return tips

@new_tips('add_module')
def sum(a,b):
    print(a+b)

a=sum(8,9)

@new_tips('sub_module')
def sub(a,b):
    print(a-b)      

全部代碼

# 裝飾器
import time

# 定義裝飾函數
# 統計執行時間
def timer(func):
    def wrapper():
        start_time=time.time()
        func()
        stop_time=time.time()
        print('運作的時間 %s' %(stop_time-start_time))
    return wrapper
#
# # 定義被裝飾函數
@timer
def i_can_sleep():
    time.sleep(3)

# 調用i_can-sleep方法
i_can_sleep()

# 執行順序,首先将i_can_sleep()傳給timer,也就是timer(i_can_sleep());
# 然後執行wrapper()函數

# 裝飾器與閉包的不同點,裝飾函數傳入的參數是一個函數,閉包傳入的參數是一個變量

print('----------------------------------------------被裝飾參數帶參數------------------------------------------------')

# 被裝飾函數帶參數,也就是裝飾函數的外部函數帶參數
# 發現需要先定義裝飾函數
def tips(func):
    def nei(a,b):  # 裝飾函數内部函數需要接收被裝飾函數的參數
        print('start')
        func(a,b)
        print('end')
    return nei

@tips
def sum(a,b):
    print(a+b)

a=sum(8,9)


print('----------------------------------------------裝飾器帶參數------------------------------------------------')
# 裝飾器帶參數
def new_tips(args):
    def tips(func):
        def nei(a,b):  # 裝飾函數内部函數需要接收被裝飾函數的參數
            print('start to %s' % args)
            func(a,b)
            print('end to %s' % args)
        return nei
    return tips

@new_tips('add_module')
def sum(a,b):
    print(a+b)

a=sum(8,9)

@new_tips('sub_module')
def sub(a,b):
    print(a-b)

b=sub(102,98)

print('--------------------------------------------擷取被裝飾函數的一些資訊--------------------------------------------------')
# 還可以擷取被裝飾函數的一些資訊
def new_tips(args):
    def tips(func):
        def nei(a,b):  # 裝飾函數内部函數需要接收被裝飾函數的參數
            print('func %s start to %s' % (func.__name__,args))
            func(a,b)
            print('func %s end to %s' % (func.__name__,args))
        return nei
    return tips

@new_tips('add_module')
def sum(a,b):
    print(a+b)

a=sum(8,9)

@new_tips('sub_module')
def sub(a,b):
    print(a-b)

b=sub(10,7)      

執行結果:

運作的時間 3.0007877349853516
----------------------------------------------被裝飾參數帶參數------------------------------------------------
start
17
end
----------------------------------------------裝飾器帶參數------------------------------------------------
start to add_module
17
end to add_module
start to sub_module
4
end to sub_module
--------------------------------------------擷取被裝飾函數的一些資訊--------------------------------------------------
func sum start to add_module
17
func sum end to add_module
func sub start to sub_module
3
func sub end to sub_module

Process finished with exit code 0