day4----函數-閉包-裝飾器

day4----函數-閉包-裝飾器

本文檔內容:

1 python中三種名稱空間和作用域

2 函數的使用

3 閉包

4 裝飾器

一?python中三種名稱空間和作用域

1.1名稱空間:

當程序運行時,代碼從上至下依次執行,它會將變量與值得關系存儲在一個空間中,這個空間
也叫命名空間。例如:name='xingchen'
當程序遇到函數時,它會將函數名存在內存中,函數內部的變量和邏輯暫時不關心;
當函數執行時,內存會臨時開辟一個空間,存放函數體里面的代碼(變量,代碼等),這個空間叫臨時名稱空間
也叫局部名稱空間。
函數外面訪問不到臨時空間的內容;隨著函數的執行完畢,臨時空間會釋放掉。
View Code

python中名稱空間分三種:
  內置名稱空間
  全局名稱空間
  局部名稱空間
作用域:
  全局作用域:
    內置名稱空間
    全局名稱空間
局部作用域:
    局部名稱空間
加載順序
內置名稱空間 ---》全局名稱空間(程序執行時) ---》局部名稱空間(函數執行時)
取值順序:單向不可逆
局部名稱空間 ---》全局名稱空間 ----》內置名稱空間

1.2 ?globals和locals

print(globals() ) 返回的是全局作用域里面的變量與其值,是一個字典

print(locals()) ? 返回的是當前的局部變量與其值,也是一個字典

例如:

def func1():a=1print(a)print(locals())print(globals())
func1()
View Code

其結果為:

1{'a': 1}{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000024FD014B240>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/PycharmProjects-x/s22day03/day4/lianxi.py', '__cached__': None, 'time': <module 'time' (built-in)>, 'func1': <function func1 at 0x0000024FD0056048>}
View Code

1.3 global和nonlocal

global:聲明一個全局變量,可以用作局部變量的關鍵字來修改或賦值給全局變量,

    但是:對可變數據類型(list,dict,set)可以直接引用不用通過global。如果默認參數是一個可變的數據類型,那么他在內存中永遠是一個

例如:下面的list就是可變數據類型,因此就不用global

# def extendList(val,list=[]):
#    list.append(val)
#    return list
# list1 = extendList(10)
# print('list1=%s'%list1) # [10,]
# list2 = extendList(123,[])
# print('list2=%s'%list2) # [123,]
# list3 = extendList('a')
# print('list3=%s'%list3) #[10,'a']# print('list1=%s'%list1)
# print('list2=%s'%list2)
# print('list3=%s'%list3)其結果為:[10,a][123][10,a]
View Code?

nonlocal:在局部作用域中,對其父級作用域(或者更外層作用域)進行變量賦值或者修改,但是不能修改全局作用域

例如:

def func1():a=1def func2():b=10def func3():nonlocal a,ba=a+1b=b+1print(a,b)   #結果為 2,11
        func3()print(a,b)       #結果為 2,11,func2函數的b被引用了
    func2()print(a)        #結果為 2,這里的變量a被引用了,但是b不是在這里面引用的,所以打印b會報錯
func1()
View Code

二函數的使用

函數名的本質就是函數的內存地址

1 函數可以被引用

例如:

def func1():print('in func1')
f=func1
print(f)
結果為:<function func1 at 0x000001E9313C6048>
View Code

2 函數可以作為容器類元素

例如

def func1():print('f1')def func2():print('f2')l1=[func1,func2]
l2={'f1':func1,'f2':func2}l1[0]()
l2['f2']()
View Code

3 函數可以作為返回值

def f1():print('f1')def func1(argv):argv()return argvf = func1(f1)
f()
View Code

其他: 第一類對象

第一類對象(first-class object)指
1.可在運行期創建
2.可用作函數參數或返回值
3.可存入變量的實體。
View Code

?三 閉包

內部函數包含對外部作用域而非全局作用域變量的引用,該內部函數稱為閉包函數,一般用于裝飾器或者網絡爬取內容

判斷閉包函數的方法__closure__

例如:

def func():name = 'eva'def inner():print(name)print(inner.__closure__) #結果中函數含有cell元素,否則為none
return inner 
f = func() 
f()
View Code

四 裝飾器

?裝飾器的本質是一個python函數,基于閉包函數,讓其他的函數在不改變源碼和調用方式的前提下,增加新的功能

?  裝飾器的應用場景:比如插入日志,性能測試,事務處理,緩存等等場景。

下面看看裝飾器的形成過程:

原始的代碼

import time
# print(time.time()) # 1527326532.2688255# def func1():
#   time.sleep(0.3)
#    print('非常復雜......')
#
# start_time = time.time()
# func1()
# end_time = time.time()
# print('此函數的執行效率%s' %(end_time-start_time))
View Code

# 改版1:我要封裝到一個函數中

# def func1():
#    time.sleep(0.3)
#    print('非常復雜......')
#
# def func2():
#    time.sleep(0.3)
#    print('特別復雜......')
#
# func1()
# func2()
View Code

# # 改版2:被測試函數當參數傳入,可以測試多個函數的執行效率

# def timmer(f):
#    start_time = time.time()
#   f()
#    end_time = time.time()
#    print('此函數的執行效率%s' %(end_time-start_time))
#
# timmer(func1)
# timmer(func2)
View Code

# 改版3::測試函數執行效率的同時,不要改變原函數的調用方式。

# def func1():
#   time.sleep(0.3)
#   print('非常復雜......')
# def func2():
#    time.sleep(0.3)
#    print('特別復雜......')
# # func1()
# # func2()
# def timmer(f):
#    start_time = time.time()
#   f()
#   end_time = time.time()
#    print('此函數的執行效率%s' % (end_time - start_time))
# f1 = func1
# func1 = timmer #
# func1(f1) # timmer(func1)
View Code

# 改版4::改版3雖然大體上滿足了我的要求,但是增加兩行代碼,
# 而且多了參數,不好,繼續改,盡量不添加其他代碼,而且做到調用時一模一樣
# 最簡單的裝飾器。

# def func1():
#   time.sleep(0.3)
#    print('非常復雜......')
# def func2():
#    time.sleep(0.3)
#    print('特別復雜......')
# # func1()
# # func2()
#
# def timmer(f): # f = func1 函數名
#    def inner():
#     start_time = time.time()
#      f()
#      end_time = time.time()
#     print('此函數的執行效率%s' % (end_time - start_time))
#    return inner
#
# func1 = timmer(func1) # inner
# func2 = timmer(func2) # inner
# func1() # inner()
# func2()
View Code

# 改版5::改版4每次測試一個函數的執行效率時,都需要加一行 func1 = timmer(func1)代碼,麻煩
# python提出了一個語法糖 @。

# def timmer(f): # f = func1 函數名
#    def inner():
#       start_time = time.time()
#       f()
#       end_time = time.time()
#       print('此函數的執行效率%s' % (end_time - start_time))
#    return inner
#
# @timmer # func1 = timmer(func1) inner
# def func1():
#    time.sleep(0.3)
#    print('非常復雜......')
#
# func1() # inner()
View Code

# 改版6:被裝飾的函數肯定要有參數的,你現在不能滿足,解決這個問題。
# 被裝飾的函數帶參數的裝飾器

# def timmer(f): # f = func1 函數名
#    def inner(*args,**kwargs): # args = (1,2),kwargs {sex:'nv',name:'alex'}
#       start_time = time.time()
#     f(*args,**kwargs) # f(1,2,,sex='nv',name='alex')
#      end_time = time.time()
#       print('此函數的執行效率%s' % (end_time - start_time))
#    return inner
#
# @timmer # func1 = timmer(func1) inner
# def func1(a,b):
#    time.sleep(0.3)
#    print(a,b)
#    print('非常復雜......')
#
#
# @timmer # func1 = timmer(func1) inner
# def func2(a,b,name,sex='man'): # f(1,2,,sex='nv',name='alex')
#    time.sleep(0.3)
#    print(a,b,sex,name)
#    print('非常復雜......')
#
# func2(1,2,sex='nv',name='alex') # inner()
View Code

# 改版7:被裝飾的函數肯定要有返回值的,解決這個問題。
# 被裝飾的函數帶參數且有返回值的裝飾器

# def timmer(f): # f = func2 函數名
#    def inner(*args,**kwargs): # args = (1,2),kwargs {sex:'nv',name:'alex'}
#       start_time = time.time()
#      ret = f(*args,**kwargs) # f(1,2,,sex='nv',name='alex')
#       end_time = time.time()
#       print('此函數的執行效率%s' % (end_time - start_time))
#      return ret
#   return inner
# @timmer # func1 = timmer(func1) inner
# def func2(a,b,name,sex='man'): # f(1,2,,sex='nv',name='alex')
#    time.sleep(0.3)
#   print(a,b,sex,name)
#    print('非常復雜......')
#    return 666
#
# print(func2(1,2,sex='nv',name='alex')) # inner()def timmer(f):def inner(*args,**kwargs):start_time = time.time()ret = f(*args,**kwargs)end_time = time.time()print('此函數的執行效率%s' % (end_time - start_time))return retreturn inner
@timmer
# def func2(a,b,name,sex='man'):
#    time.sleep(0.3)
#    print(a,b,sex,name)
#    print('非常復雜......')
#    return 666
#
# ret1 = func2(1,2,sex='nv',name='alex')
# print(ret1)
View Code
至此裝飾器的固定結構如下
def timer(func):def inner(*args,**kwargs):'''執行函數之前要做的'''re = func(*args,**kwargs)'''執行函數之后要做的'''return rereturn inner
View Code

?但是如何函數有很多,如何取消他們呢,以后如果又加上呢---帶參數的裝飾器模型

def outer(flag):def timer(func):def inner(*args,**kwargs):if flag:print('''執行函數之前要做的''')re = func(*args,**kwargs)if flag:print('''執行函數之后要做的''')return rereturn innerreturn timer@outer(False)  #改為false是不執行裝飾器內的內容
def func():print(111)func()
View Code

如果多個裝飾器裝飾一個函數呢

def wrapper1(func):def inner():print('wrapper1 ,before func')func()print('wrapper1 ,after func')return innerdef wrapper2(func):def inner():print('wrapper2 ,before func')func()print('wrapper2 ,after func')return inner@wrapper1
@wrapper2
def f():print('in f')
f()
View Code

其結果為:

wrapper1 ,before func
wrapper2 ,before func
in f
wrapper2 ,after func
wrapper1 ,after func
View Code

?裝飾器的另外一種方法:

import functools
def wrapper(func):@functools.wraps(func)def inner(*args, **kwargs):print('我是裝飾器')return func(*args,**kwargs)print('--------')return inner@wrapper
def index():print('我是被裝飾函數')return None

index()

?

?

?

---------------------------------------------------------------------------------回頂部----------------------------------------------------------------------------------------------------------------------------

posted on 2018-05-30 10:16 dawn-liu 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/mmyy-blog/p/9109425.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280205.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280205.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280205.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

濾波器和均衡器有什么區別_什么是均衡器,它如何工作?

濾波器和均衡器有什么區別It’s in your car, home theater system, phone, and audio player but it doesn’t have an instruction manual. It’s an equalizer, and with a little know-how you can tweak your audio and fall in love with it all over again. 它在您的汽車…

網絡視頻監控與人臉識別

明天又要去面試了&#xff0c;趁次機會也將以前做的東西總結一下&#xff0c;為以后理解提供方便&#xff0c;也再加深下印象。 網絡視頻監控與人臉識別主要由三個程序組成&#xff1a;1、視頻采集與傳輸程序&#xff1b;2、接受與顯示程序&#xff1b;3、人臉識別程序。下面就…

esxi.主機配置上聯端口_為什么現代的電腦機箱仍然具有USB 2.0端口?

esxi.主機配置上聯端口With USB 3.0 becoming more prevalent with each passing year now, you may have found yourself wondering why modern computers still have USB 2.0 ports built into them. With that in mind, today’s SuperUser Q&A post has the answers to…

使用命令導入、導出mysql數據

1.導出全部數據庫 利用mysqldump的—all-databases參數可以一口氣把你數據庫root用戶下的所有數據庫一口氣導出到一個sql文件里。然后&#xff0c;重裝系統后使用source命令可以再一口氣倒回來。 需要確定mysql安裝的路徑&#xff1a;本機是&#xff1a;C:\Program Files\MySQL…

面試--跨域--cors

cors是什么 cors 跨域資源共享 Cross-origin resource sharing是一種跨域的解決方案 它允許瀏覽器向跨源服務器&#xff0c;發出XMLHttpRequest請求&#xff0c;從而克服了AJAX只能同源使用的限制。 但是需要瀏覽器的支持。值得注意的是&#xff1a;整個CORS通信過程&#xff0…

【原理圖操作】原理圖更新PCB時未改動元器件布局變動問題?

轉載PCB布局、布線完工之后&#xff0c;由于設計功能&#xff0c;發現不完善時, 原理圖部分功能需要改動&#xff0c;再改原理圖&#xff0c;修改完成后&#xff0c;導入PCB過程中&#xff0c;發現PCB中未改動&#xff08;部分&#xff09;的元器件 布局發生了變化&#xff0c;…

關閉edge任務欄預覽_如何在Microsoft Edge中關閉選項卡預覽

關閉edge任務欄預覽Now that it has extension support, Microsoft Edge is becoming a more and more viable browser. One feature people seem to either love or hate is the pop-up preview you get when you hover over a tab. There’s no built-in setting that lets y…

oracle 創建view時,授權給用戶

解決方法&#xff1a; 以dba用戶登錄 sqlplus / as sysdba 賦予scott用戶創建VIEW的權限 grant create view to scott 以scott用戶登錄oracle conn scott/tiger 創建視圖成功 CREATE OR REPLACE VIEW myview AS 轉載于:https://www.cnblogs.com/523823-wu/p/7635436.html

[BZOJ 1072] 排列perm

Link&#xff1a; BZOJ 1072 傳送門 Solution&#xff1a; 一道直接next_permutation純暴力就能過的題&#xff1f; 難道2007年時大家都不知道next_permutation這個函數嗎 還是用復雜度更優的狀壓DP吧 設$dp[i][j]$為狀態為$i$且對$d$余$j$的個數&#xff0c; 注意$dp[(1<&l…

智能手機丟失 數據安全_丟失智能手機時該怎么辦

智能手機丟失 數據安全Phones get stolen or lost everyday. With a plethora of data ripe for identity-theft on it, a lost phone can easily make your blood run cold. Take a deep breath, How-To Geek will talk you through this. 手機每天都會被盜或丟失。 隨著大量用…

程序員怎樣成為一名架構師?

在今天的技術圈&#xff0c;可能隨便遇到一個人遞給你一張名片&#xff0c;title 就是某某架構師。架構師多如過江之鯽&#xff0c;也正是眼下業內一個有趣的現象。對于架構師&#xff0c;你有什么看法&#xff1f;什么是架構師&#xff1f;隨便打開某招聘網站&#xff1a;系統…

C++設計模式之工廠模式(1)

關于設計模式的作用&#xff1a; “幫助我們將應用組織成容易了解&#xff0c;容易維護&#xff0c;具有彈性的架構&#xff0c;建立可維護的OO系統&#xff0c;要訣在于隨時想到系統以后可能需要的變化以及應付變化的原則。” 具體可參考&#xff1a;https://www.cnblogs.com/…

共享沒有權限訪問權限_如何與家人共享SmartThings訪問權限

共享沒有權限訪問權限If you have multiple people in your household and want them all to have access to SmartThings from their phones, here’s how to share access to SmartThings with anyone you want. 如果您的家庭中有多個人&#xff0c;并且希望他們所有人都可以…

PABX

自動用戶小交換機;&#xff3b;私用自動交換分機&#xff3d; A private telephone exchange that automatically connects internal “branch” lines to the external circuits of a telephone system. 一種自動地將內部用戶線連接到電話系統外線的專用電話交換機。 Private …

使用jquery+css實現瀑布流布局

雖然可以直接使用css實現瀑布流布局&#xff0c;但顯示的方式有點問題&#xff0c;所以這兒就直接使用jquerycss來實現瀑布流布局&#xff0c;最終效果如下&#xff1a; 思路是通過將每個小塊的position設置為relative&#xff0c;然后計算出在當前選擇的列下應該上移的距離&am…

geek_How-To Geek正在尋找安全作家

geekThink you have the perfect combination of geek knowledge and writing skills? We’re looking for an experienced, security-focused writer to join our team. 認為您將怪胎知識和寫作技能完美結合了嗎&#xff1f; 我們正在尋找經驗豐富&#xff0c;注重安全性的作…

AAC 文件解析及解碼流程

OUTLINE&#xff1a; &#xff0a; AAC概述 &#xff0a; AAC規格簡述 &#xff0a; AAC特點 &#xff0a; AAC音頻文件解析 ——ADIF&#xff06;ADTS格式 ——ADIF&#xff06;ADTS頭信息 ——ADIF&#xff06;ADTS數據信息 ——AAC文件處理流程 &#xff0a; AAC解碼流程…

JDK8之Stream新特性

/***JDK8 Stream特性* Created by chengbx on 2018/5/27.* Java 8 中的 Stream 是對集合&#xff08;Collection&#xff09;對象功能的增強&#xff0c;它專注于對集合對象進行各種非常便利、高效的聚合操作&#xff08;aggregate operation&#xff09;&#xff0c;* 或者大…

雞蛋學運維-2:Rsync同步配置步驟

說明&#xff1a;系統環境CentOS release 6.5 (Final) 2.6.32-431.el6.x86_64rsync server:配置步驟1、vi /etc/rsyncd.conf#Rsync server#created by lijianfeng 18:26 2017-9-24#rsyncd.conf start#uid rsyncgid rsyncuse chroot nomax connections 2000timeout 600pid…

IntelliJ IDEA代碼分屏顯示

轉載于:https://www.cnblogs.com/EasonJim/p/9124809.html