1. 程式人生 > >python 函數的作用域,閉包函數的用法

python 函數的作用域,閉包函數的用法

引用 包括 body tor bsp ini www. 閉包 修改

一、三元表達式

if條件成功的值 if 條件 else else條件成功的值

#if條件成立的結果 if 條件 else else條件成立的結果
# a = 20
# b = 10
# c = 5 if a>b else 10
# print(c)

二、函數的命名空間

命名空間一共分為三種:

  全局命名空間

  局部命名空間

  內置命名空間

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

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

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

取值:

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

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

print(10)

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

技術分享圖片
def fun(a,b,c):
    return max(a,b,c)#用的是內置命名空間的max
print(fun(1,2,3))


def max(a,b):
    c=a  if a>b else b
    return c
print(max(1,5))#用的1是自己定義的max 全局作用域裏面的
技術分享圖片

三、函數的作用域:

作用域

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

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

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

globals和locals方法

print(globals())
print(locals())
技術分享圖片

a = 20
b = 50
def haha():
x = 1
y = 2
print(globals()) #全局作用域中的名字
print(locals()) #局部作用域中的名字

# haha()
# print(globals()) #全局作用域中的名字
# print(locals()) #全局的局部還是全局

技術分享圖片

global關鍵字

技術分享圖片
a = 10
def func():
    global a
    a = 20

print(a)
func()
print(a)
技術分享圖片

技術分享圖片
#作用域
#命名空間+作用域是分不開的
#兩種
#全局作用域:全局命名空間、內置命名空間
#局部作用域:局部命名空間

#小範圍的可以用大範圍的
#但是大範圍的不能用小範圍的
#範圍從大到小(圖)
#在小範圍內,如果要用一個變量,是當前這個小範圍有的,就用自己的
#如果在小範圍內沒有,就用上一級的,上一級沒有就用上上一級的,以此類推。
#如果都沒有,報錯


def func(): return max(1,2,3) # print(func()) def max(a,b,c): return 2 # print(max(1,2,3)) #站在全局看: #使用名字: # 如果全局有:用全局的 # 如果全局沒有:用內置的 #為什麽要有作用域的概念: #為了函數內的變量不會影響到全局 # def max(): # a = 10 # b = 20 # # a = 2 # b = 3 # my_max(30,50)
技術分享圖片

四、函數嵌套和作用域鏈

函數嵌套

技術分享圖片
def f1():
    def f2():
        def f3():
            print("in f3")
        print("in f2")
        f3()
    print("in f1")
    f2()
    
f1()
技術分享圖片

函數作用域鏈

技術分享圖片
def f1():
    a = 1
    def f2():
        def f3():
            print(a)
        f3()
    f2()

f1()
技術分享圖片 技術分享圖片
def f1():
    a = 1
    def f2():
        a = 2
    f2()
    print(‘a in f1 : ‘,a)

f1()
技術分享圖片

nonlocal關鍵字

技術分享圖片
def f():
    a = 3
    def f1():
        a = 1
        def f2():
            nonlocal a
            # 1.外部必須有這個變量
            # 2.在內部函數聲明nonlocal變量之前不能再出現同名變量
            # 3.內部修改這個變量如果想在外部有這個變量的第一層函數中生效

            a = 2
        f2()
        print(‘a in f1 : ‘, a)
    f1()
    print(‘a in f : ‘,a)

f()
技術分享圖片

函數名的本質

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

1.可以被引用

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‘]()
技術分享圖片

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

技術分享圖片
__author__ = ‘Administrator‘
def f():
    print("so good")
    return 1+2
l=f#函數名實際上就是普通的變量名
#print(l())

def g(f):#函數名可以做參數
    print(f)#結果是函數名所指向的那塊內存地址
    print("so good g")
    return 2+5
print(g(f))



def l():
    return f#函數名可用作返回值

ll=l()
print(ll())
技術分享圖片

五.閉包

閉包
1.閉 內部的函數
2.包 包含了對外部函數作用域中變量的引用

閉包的作用:

就是能夠引用外部函數的變量,並且可以保證外部函數的變量控制在一個局部作用域中

技術分享圖片
#閉包的常用形式
def hei():
    x = 20
    def inner():
        print(x)  #局部的
    return inner

# i = hei()
# i()  #全局
技術分享圖片 技術分享圖片
__author__ = ‘Administrator‘
# from urllib.request import urlopen
# def fun():
#     url="http://www.sina.com.cn/"
#     def op():
#         return urlopen(url).read()
#     return op
# l=fun()
# print(l())
from urllib.request import urlopen
def fun(url):
    def op():
        return urlopen(url).read()
    return op
url="http://www.sina.com.cn/"
l=fun(url)
print(l())
技術分享圖片

判斷閉包函數的方法__closure__

技術分享圖片
#輸出的__closure__有cell元素 :是閉包函數
def func():
    name = ‘eva‘
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f = func()
f()

#輸出的__closure__為None :不是閉包函數
name = ‘egon‘
def func2():
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f2 = func2()
f2()
技術分享圖片
1 2 3 4 5 6 7 8 9 10 11 12 13 #閉包嵌套 def wrapper(): money = 1000 def func(): name = ‘eva‘ def inner(): print(name,money) return inner return func f = wrapper() i = f() i()

  

小節:

命名空間:

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

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

  調用時,如果在自己的空間內有,就用自己的。如果沒有就使用大範圍的。不能從大範圍中用小範圍的。

函數的嵌套:

  嵌套調用

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

函數名的本質:

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

閉包:

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

python 函數的作用域,閉包函數的用法