python之路day10-命名空間和作用域、函數嵌套,作用域鏈、閉包

楔子

假如有一個函數,實現返回兩個數中的較大值:

def my_max(x,y):m = x if x>y else yreturn m
bigger = my_max(10,20)
print(bigger)

之前是不是我告訴你們要把結果return回來你們就照做了?可是你們有沒有想過,我們為什么要把結果返回?如果我們不返回m,直接在程序中打印,行不行?

來看結果:

>>> def my_max(x,y):
...     m = x if x>y else y
... 
>>> my_max(10,20)
>>> print(m)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
NameError: name 'm' is not defined

報錯了!錯誤是“name 'm' is not defined”。變量m沒有被定義。。。為啥?我明明定義了呀!

在這里我們首先回憶一下python代碼運行的時候遇到函數是怎么做的。

從python解釋器開始執行之后,就在內存中開辟了一個空間

每當遇到一個變量的時候,就把變量名和值之間的對應關系記錄下來。

但是當遇到函數定義的時候解釋器只是象征性的將函數名讀入內存,表示知道這個函數的存在了,至于函數內部的變量和邏輯解釋器根本不關心。

等執行到函數調用的時候,python解釋器會再開辟一塊內存來存儲這個函數里的內容,這個時候,才關注函數里面有哪些變量,而函數中的變量會存儲在新開辟出來的內存中。函數中的變量只能在函數的內部使用,并且會隨著函數執行完畢,這塊內存中的所有內容也會被清空。

我們給這個“存放名字與值的關系”的空間起了一個名字——叫做命名空間

代碼在運行伊始,創建的存儲“變量名與值的關系”的空間叫做全局命名空間,在函數的運行中開辟的臨時的空間叫做局部命名空間

命名空間和作用域

命名空間的本質:存放名字與值的綁定關系

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

python之禪


復制代碼
>>> import this
The Zen of Python, by Tim PetersBeautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
復制代碼

在python之禪中提到過:命名空間是一種絕妙的理念,讓我們盡情的使用發揮吧!

?

命名空間一共分為三種:

  全局命名空間

  局部命名空間

  內置命名空間

*內置命名空間中存放了python解釋器為我們提供的名字:input,print,str,list,tuple...它們都是我們熟悉的,拿過來就可以用的方法。

三種命名空間之間的加載與取值順序:

加載順序:內置命名空間(程序運行前加載)->全局命名空間(程序運行中:從上到下加載)->局部命名空間(程序運行中:調用時才加載)

取值:

  在局部調用:局部命名空間->全局命名空間->內置命名空間

x = 1
def f(x):print(x)print(10)

x = 1
def f(x):print(x)print(10)

  在全局調用:全局命名空間->內置命名空間

x = 1
def f(x):print(x)f(10)
print(x)

x = 1
def f(x):print(x)f(10)
print(x)
print(max)

print(max)

?

?

作用域

作用域就是作用范圍,按照生效范圍可以分為全局作用域和局部作用域。

全局作用域:包含內置名稱空間、全局名稱空間,在整個文件的任意位置都能被引用、全局有效

局部作用域:局部名稱空間,只能在局部范圍生效

globals和locals方法

print(globals())
print(locals())

print(globals())
print(locals())
def func():a = 12b = 20print(locals())print(globals())func()

復制代碼
def func():a = 12b = 20print(locals())print(globals())func()
復制代碼

global關鍵字

a = 10
def func():global aa = 20print(a)
func()
print(a)

函數的嵌套和作用域鏈

函數的嵌套調用


def max2(x,y):m  = x if x>y else yreturn mdef max4(a,b,c,d):res1 = max2(a,b)res2 = max2(res1,c)res3 = max2(res2,d)return res3# max4(23,-7,31,11)
復制代碼
def max2(x,y):m  = x if x>y else yreturn mdef max4(a,b,c,d):res1 = max2(a,b)res2 = max2(res1,c)res3 = max2(res2,d)return res3# max4(23,-7,31,11)
復制代碼

  函數的嵌套定義

def f1():print("in f1")def f2():print("in f2")f2()
f1()
def f1():def f2():def f3():print("in f3")print("in f2")f3()print("in f1")f2()f1()

?  函數的作用域鏈

def f1():a = 1def f2():print(a)f2()f1()
def f1():a = 1def f2():def f3():print(a)f3()f2()f1()
def f1():a = 1def f2():a = 2f2()print('a in f1 : ',a)f1()
復制代碼
def f1():a = 1def f2():a = 2f2()print('a in f1 : ',a)f1()
復制代碼

?   nonlocal關鍵字

1.外部必須有這個變量
2.在內部函數聲明nonlocal變量之前不能再出現同名變量
3.內部修改這個變量如果想在外部有這個變量的第一層函數中生效
def f1():a = 1def f2():nonlocal aa = 2f2()print('a in f1 : ',a)f1()
復制代碼
def f1():a = 1def f2():nonlocal aa = 2f2()print('a in f1 : ',a)f1()
 

函數名的本質

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

1.可以被引用


def func():print('in func')f = func
print(f)
def func():print('in func')f = func
print(f)

2.可以被當作容器類型的元素

def f1():
print('f1')


def f2():
print('f2')


def f3():
print('f3')

l = [f1,f2,f3]
d = {'f1':f1,'f2':f2,'f3':f3}
#調用
l[0]()
d['f2']()

函數被當作容易類型的元素

復制代碼
def f1():print('f1')def f2():print('f2')def f3():print('f3')l = [f1,f2,f3]
d = {'f1':f1,'f2':f2,'f3':f3}
#調用
l[0]()
d['f2']()
復制代碼

3.可以當作函數的參數和返回值

*不明白?那就記住一句話,就當普通變量用

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

閉包

def func():name = 'eva'def inner():print(name)

閉包函數:

內部函數包含對外部作用域而非全劇作用域名字的引用,該內部函數稱為閉包函數
#函數內部定義的函數稱為內部函數

?

由于有了作用域的關系,我們就不能拿到函數內部的變量和函數了。如果我們就是想拿怎么辦呢?返回呀!

我們都知道函數內的變量我們要想在函數外部用,可以直接返回這個變量,那么如果我們想在函數外部調用函數內部的函數呢?

是不是直接就把這個函數的名字返回就好了?

這才是閉包函數最常用的用法

def func():name = 'eva'def inner():print(name)return innerf = func()
f()

判斷閉包函數的方法__closure__

#輸出的__closure__有cell元素 :是閉包函數
def func():name = 'eva'def inner():print(name)print(inner.__closure__)return innerf = func()
f()#輸出的__closure__為None :不是閉包函數
name = 'egon'
def func2():def inner():print(name)print(inner.__closure__)return innerf2 = func2()
f2()
?閉包嵌套

def wrapper():
money = 1000
def func():
name = 'eva'
def inner():
print(name,money)
return inner
return func

f = wrapper()
i = f()
i()

閉包嵌套

閉包函數獲取網絡應用 小爬蟲
from urllib.request import urlopendef index():url = "http://www.xiaohua100.cn/index.html"def get():return urlopen(url).read()return getxiaohua = index()
content = xiaohua()
print(content)

本章小結

命名空間:

  一共有三種命名空間從大范圍到小范圍的順序:內置命名空間、全局命名空間、局部命名空間

作用域(包括函數的作用域鏈):

小范圍的可以用大范圍的
但是大范圍的不能用小范圍的
范圍從大到小(圖)

在小范圍內,如果要用一個變量,是當前這個小范圍有的,就用自己的
如果在小范圍內沒有,就用上一級的,上一級沒有就用上上一級的,以此類推。
如果都沒有,報錯

函數的嵌套:

  嵌套調用

  嵌套定義:定義在內部的函數無法直接在全局被調用

函數名的本質:

  就是一個變量,保存了函數所在的內存地址

閉包:

  內部函數包含對外部作用域而非全劇作用域名字的引用,該內部函數稱為閉包函數



轉載于:https://www.cnblogs.com/hanfe1/p/10429690.html

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

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

相關文章

hive(II)--sql考查的高頻問題

在了解別人hive能力水平的時候&#xff0c;不管是別人問我還是我了解別人&#xff0c;有一些都是必然會問的東西。問的問題也大都大同小異。這里總結一下我遇到的那些hive方面面試可能涉及的問題 1、行轉列&#xff08;列轉行&#xff09; 當我們建設數據倉庫時&#xff0c;我們…

java概述

一、java平臺無關&#xff1a;jvm二、java健壯語言&#xff1a;無指針&#xff0c;語法上無指正&#xff0c;無內存申請與釋放。 三、java核心機制而&#xff1a; jvmjava垃圾收集機制 GC四、java運行過程&#xff1a;源程序&#xff08;.java&#xff09;——》java編譯器——…

時間間隔

計算當前時間與上次執行時間的時間間隔。 NSTimeInterval timetravel [[NSDate date]timeIntervalSinceDate:self.lastPlaySoundDate];if (timetravel<3.0) {DLog("時間太短&#xff0c;。。");}self.lastPlaySoundDate [NSDate date]; 轉載于:https://www.cnb…

.Net+MySQL組合開發(二) 數據訪問篇

一、建立數據庫、表、添加數據這里我們使用圖形化操作的SQL Manager 2005 Lite for MySQL來建立數據&#xff0c;它的操作界面非常類似OFFICE軟件&#xff0c;使用方便、很容量上手、下面開始建立數據庫及表單擊"Creat New DataBase"&#xff1a;新建DB輸入密碼&…

Git vs SVN

一、Git vs SVN Git 和 SVN 孰優孰好&#xff0c;每個人有不同的體驗。Git是分布式的&#xff0c;SVN是集中式的這是 Git 和 SVN 最大的區別。若能掌握這個概念&#xff0c;兩者區別基本搞懂大半。因為 Git 是分布式的&#xff0c;所以 Git 支持離線工作&#xff0c;在本地可以…

.net api 和java平臺對接技術總結

這兩天 一直和京東對接接口&#xff0c;我們用.net api 提供接口&#xff0c;對方用java調用&#xff0c;本來沒什么問題&#xff0c;但是對方對數據安全要求特別嚴&#xff0c;要驗簽&#xff0c;于是噩夢開始了。 1、在傳輸的時候&#xff0c;約定傳輸格式&#xff1a; HttpW…

Burpsuite學習(4)

2019獨角獸企業重金招聘Python工程師標準>>> burpsuite spider模塊通過跟蹤 HTML 和 JavaScript 以及提交的表單中的超鏈接來映射目標應用程序&#xff0c;它還使用了一些其他的線索&#xff0c;如目錄列表&#xff0c;資源類型的注釋&#xff0c;以及 robots.txt 文…

Git刪除分支/恢復分支

這是https://www.cnblogs.com/utank/p/7880441.html的方法&#xff0c;雖然很老現在有點不一樣&#xff0c;但總體還是能用的。 總結就是兩種方法 1.用commit的id恢復 2.用reflog的頭指針恢復 ?刪除一個已被終止的分支 如果需要刪除的分支不是當前正在打開的分支&#xff0c;使…

NetCore2.0Web應用之Startup

為什么80%的碼農都做不了架構師&#xff1f;>>> 作為main函數的程序啟動文件UseStartup 默認就是調用我們的整個應用程序的啟動文件 class Program{static void Main(string[] args){var host new WebHostBuilder().UseKestrel() // 指定WebServer為Kes…

windows XP系統下oracle完整卸載過程

NT環境下&#xff1a; 1、以NT的Administrator 登陸 2、通過控制面版-〉服務&#xff0c;停掉所有ORACLE服務 3、打開注冊表&#xff08;REGEDIT命令&#xff09;&#xff0c;刪除HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE 4、打開注冊表中的 HKEY_LOCAL_MACHINE\SYSTEM\CurrentCont…

Hadoop----hdfs的基本操作

2019獨角獸企業重金招聘Python工程師標準>>> HDFS操作文件的基本命令 1.創建文件夾 $>hdfs dfs -mkdir /user/centos/hadoop 2.展示目錄 $>hdfs dfs -ls -r /user/centos/hadoop 3.遞歸展示 $>hdfs dfs -lsr /user/centos/hadoop 4.上傳文件 $&g…

原生sql實現restful接口調用

index.php <?phpinclude ./Request.php; include ./Response.php; //獲取數據 $dataRequest::getRequest(); $resultResponse::sendResponse($data); echo $result; ?> Request.php <?php class Request{private static $method_typearray(get,post,put,delete,pa…

彈幕效果

<!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title>彈幕效果</title> <script src"../../jquery-1.12.4.min.js" type"text/javascript" charset"utf-8"></script> </h…

基于.NetCore開發博客項目 StarBlog - (21) 開始開發RESTFul接口

1前言最近電腦壞了&#xff0c;開源項目的進度也受到一些影響這篇醞釀很久了&#xff0c;作為本系列第二部分&#xff08;API接口開發&#xff09;的第一篇&#xff0c;得想一個好的開頭&#xff0c;想著想著就鴿了好久&#xff0c;索性不扯那么多了&#xff0c;直接開寫吧~2關…

03 Oracle分區表

Oracle分區表 先說句題外話… 歡迎成都天府軟件園的小伙伴來面基交流經驗~ 一&#xff1a;什么是分區&#xff08;Partition&#xff09;&#xff1f; 分區是將一個表或索引物理地分解為多個更小、更可管理的部分。 分區對應用透明&#xff0c;即對訪問數據庫的應用而言&…

windows獲取本地時間_如何在Windows 8中重新獲得本地登錄

windows獲取本地時間By default a fresh Windows 8 installation prompts you to create a synchronized cloud-enabled login. While there are distinct perks to Microsoft’s live login system, sometimes you just want to keep things simple and local. Read on as we …

如何解決高并發,秒殺問題

相信不少人會被這個問題困擾&#xff0c;分享大家一篇這樣的文章&#xff0c;希望能夠幫到你&#xff01; 一、秒殺業務為什么難做&#xff1f;1&#xff09;im系統&#xff0c;例如qq或者微博&#xff0c;每個人都讀自己的數據&#xff08;好友列表、群列表、個人信息&#xf…

Spring原理之代理與動態代理模式總結(四)

2019獨角獸企業重金招聘Python工程師標準>>> 代理模式 1&#xff0c;什么是代理模式&#xff1f; 代理模式的作用是&#xff1a;為其他對象提供一種代理以控制對這個對象的訪問。2&#xff0c;代理模式有什么好處&#xff1f; 在某些情況下&#xff0c;一個客戶不…

可執行文件添加快捷方式_如何停止Windows向快捷方式文件名添加“-快捷方式”...

可執行文件添加快捷方式When you make a new shortcut in Windows, it automatically adds “- Shortcut” to the end of the shortcut’s file name. This doesn’t seem like a big deal, but they can be bothersome. Sure, you can remove the text yourself when you cre…

Red hat6.4重新安裝yum

今天在Red Hat上安裝軟件時&#xff0c;發現需要依賴軟件&#xff0c;然而在用yum指令時&#xff0c;出現了下面的錯誤&#xff1a; This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. 出現這個問題的原因是&…