Python函數(shù),變量,閉包

Python中函數(shù)可以設(shè)定默認(rèn)值。
Python是dynamically typed的,可以接收任何數(shù)據(jù)類型,函數(shù)的參數(shù)也是,不用考慮輸入的數(shù)據(jù)類型,而是將其交給具體的代碼去判斷執(zhí)行,但是缺點(diǎn)是,必須在函數(shù)的開頭加上數(shù)據(jù)的類型檢查。

函數(shù)的嵌套

Python的函數(shù)支持嵌套

def f1():
    print('hello')
    def f2():
        print('world')
    f2()
f1()
 
# 輸出
hello
world

函數(shù)嵌套的作用:

  • 能夠保證內(nèi)部函數(shù)的隱私,內(nèi)部函數(shù)只能被外部函數(shù)訪問,不會(huì)暴露全局作用域。比如一些隱私數(shù)據(jù),數(shù)據(jù)庫(kù)的用戶名和密碼等。
def connect_DB():
    def get_DB_configuration():
        ...
        return host, username, password
    conn = connector.connect(get_DB_configuration())
    return conn
  • 合理的使用函數(shù)嵌套,能夠提高程序的運(yùn)行效率,可以看下遞歸的python代碼,求一個(gè)數(shù)的階乘:
def factorial(input):
    # validation check
    if not isinstance(input, int):
        raise Exception('input must be an integer.')
    if input < 0:
        raise Exception('input must be greater or equal to 0' )
    ...
 
    def inner_factorial(input):
        if input <= 1:
            return 1
        return input * inner_factorial(input-1)
    return inner_factorial(input)
 
 
print(factorial(5))

使用函數(shù)嵌套,輸入是否合法的檢查就只需要一次,如果不使用函數(shù)嵌套,就需要在inner_factorial中繼續(xù)做參數(shù)檢查

變量

  • 注意:函數(shù)內(nèi)部不能隨意改變?nèi)肿兞康闹?/strong>
MIN_VALUE = 1
MAX_VALUE = 10
def validation_check(value):
    ...
    MIN_VALUE += 1
    ...
validation_check(5)

MIN_VALUE和MAX_VALUE都是全局變量,這樣會(huì)報(bào)錯(cuò)

UnboundLocalError: local variable 'MIN_VALUE' referenced before assignment

因?yàn)?,Python的解釋器會(huì) 默認(rèn)函數(shù)內(nèi)部的變量 是局部變量,但是發(fā)現(xiàn)局部變量MIN_VALUE并沒有聲明,所以無法執(zhí)行相關(guān)操作。如果一定要在函數(shù)內(nèi)部改變?nèi)肿兞康闹担仨毤由?global 聲明:

MIN_VALUE = 1
MAX_VALUE = 10
def validation_check(value):
    global MIN_VALUE
    ...
    MIN_VALUE += 1
    ...
validation_check(5)

如果遇到函數(shù)內(nèi)部局部變量和全局變量同名的情況,在函數(shù)內(nèi)部,局部變量會(huì)覆蓋全局的變量。

  • 嵌套函數(shù),內(nèi)部函數(shù)可以訪問外部函數(shù)定義的變量,但是無法修改,若要修改,必須加上 nonlocal 這個(gè)關(guān)鍵字
def outer():
    x = "local"
    def inner():
        nonlocal x # nonlocal 關(guān)鍵字表示這里的 x 就是外部函數(shù) outer 定義的變量 x
        x = 'nonlocal'
        print("inner:", x)
    inner()
    print("outer:", x)
outer()
# 輸出
inner: nonlocal
outer: nonlocal

閉包(closure)

閉包和嵌套函數(shù)類似,只是閉包外部函數(shù)的返回值是內(nèi)部函數(shù)

def nth_power(exponent):
    def exponent_of(base):
        return base ** exponent

    return exponent_of  # 返回值是 exponent_of 函數(shù)


square = nth_power(2)  # 計(jì)算一個(gè)數(shù)的平方
cube = nth_power(3)  # 計(jì)算一個(gè)數(shù)的立方

print(square)
print(cube)

print(square(2))
print(cube(2))

<function nth_power.<locals>.exponent_of at 0x000002599895B5E0>
<function nth_power.<locals>.exponent_of at 0x000002599895B550>
4
8

使用閉包的一個(gè)原因是,閉包能讓程序變得更加簡(jiǎn)潔易讀,上面的邏輯其實(shí)可以直接寫成

def nth_power_rewrite(base, exponent):
    return base ** exponent

但是,調(diào)用時(shí)區(qū)別就出來了

# 不適用閉包
res1 = nth_power_rewrite(base1, 2)
res2 = nth_power_rewrite(base2, 2)
res3 = nth_power_rewrite(base3, 2)
...
 
# 使用閉包
square = nth_power(2)
res1 = square(base1)
res2 = square(base2)
res3 = square(base3)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容