1. 程式人生 > >函數名的應用(第一對象) 閉包 裝飾器

函數名的應用(第一對象) 閉包 裝飾器

urlopen 測試 就是 復制代碼 name cti 分享 流程 .cn

函數名的應用(第一對象)。
# 1,直接打印函數名得到的是函數的內存地址 <function func1 at 0x0000000002876B70>
# print(func1)
#2,函數名可以賦值運算。
# def func1():
#     print(666)
# f1 = func1
# f1()

# 3, 函數名可以作為函數的參數。
技術分享圖片
# def func1():
#     print(666)
#
# def func2(x):
#     x()
#     print(555)
# func2(func1)
技術分享圖片

 
# 4,函數名可以作為容器類數據類型的元素。
技術分享圖片
# def func1():
#     print(666)
#
# def func2():
#     print(222)
#
# def func3():
#     print(111)
#
# def func4():
#     print(777)
# l1 = [func1, func2, func3, func4]
# for i in l1:
#     i()
# dic1 = {
#     1:func1,
#     2:func2,
#     3:func3,
#     4:func4,
# }
# dic1[1]()
技術分享圖片

 
# 5,函數名可以當做函數的返回值

技術分享圖片

技術分享圖片  運行流程為再給ret賦值操作時調用了一次func2函數,並把func1函數名賦值給x,此時print 222,並且返回x也就是返回func1,此時:x = func1 = ret,然後執行ret()打印666。

或者寫成:

技術分享圖片

輸出結果一樣,x = func1 ,x() = func1()

03,閉包。
# 內層函數對外層函數非全局變量的引用就叫閉包
#判斷是不是閉包 函數名.__closure__
# 返回的None則不是閉包,返回的是cell.... 則是閉包
# 閉包有什麽用?
#當執行一個函數時,如果解釋器判斷此函數內部閉包存在,這樣
#Python就一個機制,閉包的所在的臨時名稱空間不會隨著函數的執行完畢而消失。


技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片  關於輸出結果:函數內的print打印的都是函數內的name,函數內的name的初始值為sky,在func2的nonlocal name 修改為alex。函數外的print打印的為全局變量,被func3修改後的wit。

from urllib.request import urlopen

def index():
    url = http://www.xiaohua100.cn/index.html
    def get():
        return urlopen(url).read()
    return get

scf = index()
content 
= scf() print(content)

技術分享圖片

等於 content = index()()

  print(content)

04,裝飾器。

#裝飾器功能:在不改變原函數的基礎上,為原函數增加一些額外的功能,log,登錄註冊,等等.


測試程序的效率
import time
‘‘‘第一版本,測試函數low‘‘‘
# def login():
#     time.sleep(0.3)
#     print(‘洗洗更健康...‘)
#
# def timmer():
#     start_time = time.time()
#     login()
#     end_time = time.time()
#     print(‘此函數的執行時間%s‘ % (end_time - start_time))
# timmer()
技術分享圖片

技術分享圖片
# 改變了我原來執行函數的執行方式,不好
# def login():
#     time.sleep(0.3)
#     print(‘洗洗更健康...‘)
# # login()
#
# def register():
#     time.sleep(0.4)
#     print(‘洗洗更健康22222...‘)
# # register()
# def timmer(f):
#     start_time = time.time()
#     f()
#     end_time = time.time()
#     print(‘此函數的執行時間%s‘ % (end_time - start_time))
#
# timmer(login)
# timmer(register)
技術分享圖片

技術分享圖片
# 雖然執行函數的方式已經無限接近於原方式,但是更麻煩了,增加了兩步代碼。改
# def login():
#     time.sleep(0.3)
#     print(‘洗洗更健康...‘)
# # login()
#
# def timmer(f):
#     start_time = time.time()
#     f()
#     end_time = time.time()
#     print(‘此函數的執行時間%s‘ % (end_time - start_time))
#
# f1 = login  # 將login函數名給了f1
# login = timmer  # 將timmer函數名給了login
# login(f1)  # timmer(login)

# 初級裝飾器
# def login():
#     time.sleep(0.3)
#     print(洗洗更健康...)
# # login()
#
# def timmer(f):  # f = login函數名
#
#     def inner():
#         start_time = time.time()
#         f()  # login()
#         end_time = time.time()
#         print(此函數的執行時間%s % (end_time - start_time))
#     return inner
#
# login = timmer(login)  # inner 此login是新變量
# login()  # inner()
# 簡單版裝飾器  語法糖
# def timmer(f):  # f = login函數名
#     def inner():
#         start_time = time.time()
#         f()  # login()
#         end_time = time.time()
#         print(‘此函數的執行時間%s‘ % (end_time - start_time))
#     return inner
#
# @timmer  # login = timmer(login)  # inner 此login是新變量
# def login():
#     time.sleep(0.3)
#     print(‘洗洗更健康...‘)
# login()

# @timmer  # register = timmer(register)
# def register():
#     time.sleep(0.2)
#     print(‘洗洗更健康22...‘)
技術分享圖片

技術分享圖片

函數名的應用(第一對象) 閉包 裝飾器