日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python函数作用域与闭包_python函数名称空间与作用域、闭包

發布時間:2024/7/23 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python函数作用域与闭包_python函数名称空间与作用域、闭包 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、命名空間概念

1、命名空間(name space)

名稱空間是存放名字的地方。

若變量x=1,1存放在內存中,命名空間是存放名字x、x與1綁定關系的地方。

2、名稱空間加載順序

python test.py

#1、python解釋器先啟動,因而首先加載的是:內置名稱空間

#2、執行test.py文件,然后以文件為基礎,加載全局名稱空間

#3、在執行文件的過程中如果調用函數,則臨時產生局部名稱空間

3、名字的查找順序

局部名稱空間——》全局名稱空間——》內置名稱空間

需要注意的是:在全局無法查看局部的,在局部可以查看全局的,如下例:

# max=1

def f1():

# max=2

def f2():

max=3

print(max)

f2()

f1()

print(max)

"""

3

"""

max=1

def f1():

# max=2

def f2():

# max=3

print(max)

f2()

f1()

print(max)

"""

1

1

"""

二、作用域

python中一個函數就是一個作用域,局部變量放置在其作用域中;代碼定義完成后,作用域已經完成,作用域鏈向上查找。類似C#、Java中作用域{}。

不同變量的作用域不同就是由這個變量所在的命名空間決定的。

1、作用域即范圍

全局范圍(內置名稱空間與全局名稱空間屬于該范圍):全局存活,全局有效

局部范圍(局部名稱空間屬于該范圍):臨時存活,局部有效

2、作用域關系是在函數定義階段就已經固定的,與函數的調用位置無關,如下:

x=1

def f1():

def f2():

print(x)

return f2

x=100

def f3(func):

x=2

func()

x=10000

f3(f1())

"""

10000

"""

3、查看作用域

LEGB 代表名字查找順序:locals ——>enclosing(相鄰的上一級) ——>globals ——> __builtins__

locals 是函數內的名字空間,包括局部變量和形參

enclosing 外部嵌套函數的名字空間

globals 全局變量,函數定義所在模塊的名字空間

builtins 內置模塊的名字空間

n = 10

def fun1():

n = 20

print('func1',n)

def fun2():

n = 30

print('func2',n)

def func3():

print("func3",n) # locals沒有,先找相鄰上一級作用域

func3() # 30

fun2() # 30

fun1() # 20

依次輸出:func1 20? ;func2 30? ; func3 30

def func():

level = 'L1'

n = 33

print(locals())

def outer():

n = 44

level = 'L2'

print(locals(), n)

def inner():

level = 'L3'

print(locals(), n)

inner() # {'n': 44, 'level': 'L3'} 44

outer() # {'n': 44, 'level': 'L2'} 44

func() # {'n': 33, 'level': 'L1'}

輸出如下結果:

{'n': 33, 'level': 'L1'}

{'level': 'L2', 'n': 44} 44

{'level': 'L3', 'n': 44} 44

三、閉包函數

內部函數包含對外部作用域而非全局作用域的引用。之前都是通過參數將外部的值傳給函數,閉包提供的思路是將參數包起來。

1、什么是閉包?

閉包,即函數定義和函數表達式位于另一個函數的函數體內(嵌套函數)。而且,這些內部函數可以訪問它們所在的外部函數中聲明的所有局部變量、參數。當其中一個這樣的內部函數在包含它們的外部函數之外被調用時,就會形成閉包。

也就是說,內部函數會在外部函數返回后被執行。而當這個內部函數執行時,它仍然必需訪問其外部函數的局部變量、參數以及其他內部函數。這些局部變量、參數和函數聲明(最初時)的值是外部函數返回時的值,但也會受到內部函數的影響。

def func():

n = 10

def func2():

print("func2:",n) # 對外部作用域的引用

return func2

f = func() # 拿到func2內存地址

print(f) # func2內存地址:.func2 at 0x101fb4620>

f() # 執行func2: 10

在外部可以執行內部的函數,并且可以使用內部函數作用域里的值,這種現象就是閉包。

在函數里面套了一層子函數,在外層函數被執行的時候,子函數被返回了,返回的是內存地址,在外面執行子函數的時候用引用了外層函數的變量,相當于兩者有一種扯不掉理還亂的關系。

2、閉包的意義和應用

閉包的意義:返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處調用,優先使用自己外層包裹的作用域。

應用領域:延遲計算(原來我們是傳參,現在是抱起來)、裝飾器

from urllib.request import urlopen

def index(url):

def get():

return urlopen(url).read()

return get

baidu = index('http://www.baidu.com')

print(baidu().decode('utf-8'))

四、函數嵌套返回值

age = 18

def func1():

age = 73

def func2():

age = 84

print(age)

return 666

val = func1()

print(val)

'''

輸出:666

'''

函數可以當做返回值:

# 函數名可以當作返回值

age = 18

def func1():

age = 73

def func2():...

return func2 # 返回一個函數名# val = func1()

print(val)

'''

輸出:.func2 at 0x101462598>

'''

# 代碼寫完之后作用域已經生成,不管函數名傳到哪里,只要執行都回回定義的地方往上找

age = 18

def func1():

age = 73

def func2():

print(age)

return func2 # 返回一個函數名不帶括號

val = func1()

val()

'''

輸出結果:73

'''

總結

以上是生活随笔為你收集整理的python函数作用域与闭包_python函数名称空间与作用域、闭包的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。