1. 程式人生 > >python學習筆記——函式(三)

python學習筆記——函式(三)

今天我們學習函式最後一部分

一 .函式:內嵌函式與閉包

(1)函式中如何修改全域性變數且對全域性產生影響??
(2)函式中是否可以再巢狀函式??
(3)倘若可以巢狀函式,內部函式是否可以引用外部函式的變數??
帶著問題進入學習——>

1.global關鍵字

因為在函式體內修改全域性變數時,python會自動採用遮蔽方式來保護全域性變數,自動建立一個同名的區域性變數,所以無論在函式體內如何修改,僅僅只是在修改這個同名的區域性變數。
如果希望在函式中修改全域性變數的值——那就要採用關鍵字global

看個例子:

>>> count=5
>>> 
def MyFun(): global count count = 10 print(count) >>> MyFun() 10 >>> print(count) 10

2.內嵌函式

python中是可以內嵌函式的,但需要注意內部函式的整個作用域都在外部函式的作用域內。
再看個例子:

>>> def fun1():
    print("gagag")
    def fun2():
        print("sjdhs")
    fun2()


>>> fun1()
gagag
sjdhs
>>> 
fun2() Traceback (most recent call last): File "<pyshell#28>", line 1, in <module> fun2() NameError: name 'fun2' is not defined

3.閉包

  不同程式語言實現閉包的方式是不同的;
  python中閉包從表現形式上看,如果在一個內部函式裡,對在外部作用域的變數進行引用,那麼內部函式就被認為是閉包(closure)。
  
看例子:  

>>> def fun1(x):
    def fun2(y)
:
return x+y return fun2

兩種傳參方式:

>>> i=fun1(6)
>>> i(4)
10

----------
>>> fun1(6)(4)
10
>>> 

3.2初學者容易犯的一個錯誤及解決

看程式碼:

>>> def fun1():
    x=5
    def fun2():
        x*=x
        return x
    return fun2()

>>> fun1()
Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    fun1()
  File "<pyshell#41>", line 6, in fun1
    return fun2()
  File "<pyshell#41>", line 4, in fun2
    x*=x
UnboundLocalError: local variable 'x' referenced before assignment

為啥呼叫函式時報錯了呢?
UnboundLocalError: local variable ‘x’ referenced before assignment,這是因為變數“x”沒有被定義就拿來使用

 
解決辦法:

第一種:在python 3之前,用容器型別解決,
因為容器型別是存放在棧中的,因此對於內部函式而言,外部函式的變數不會被遮蔽掉,那就可以訪問外部函式的變數。

直接看程式碼:

def fun1():
    x=[5]
    def fun2():
        x[0]*=x[0]
        return x[0]
    return fun2()

>>> fun1()
25

第二種:想一下,python這麼靈活,當想在函式中修改全域性變數的值時,創造了關鍵字global,
那麼,當希望在內部函式修改外部函式的區域性變數,就創造了nonlocal關鍵字啦

>>> def fun1():
    x=5
    def fun2():
        nonlocal x
        x*=x
        return x
    return fun2()

>>> fun1()
25

二.函式:lambda表示式

1.lambda表示式

  • Lambda 表示式(lambda expression)是一個匿名函式
  • Lambda 表示式作用:
    1)Python寫一些執行指令碼時,使用lambda就可以省下定義函式過程,比如說我們只是需要寫個簡單的指令碼來管理伺服器時間,我們就不需要專門定義一個函式然後再寫呼叫,使用lambda就可以使得程式碼更加精簡。

    2)對於一些比較抽象並且整個程式執行下來只需要呼叫一兩次的函式,有時候給 函式起個名字也是比較頭疼的問題,使用lambda就不需要考慮函式命名的問題了。

    3)簡化程式碼的可讀性

  • 如何使用直接看程式碼例子:


>>> def func(x):
    return 3 * x

>>> func(5)
15
>>> g=lambda x:3 * x
>>> g(5)
15

2..filter()——實現過濾功能

使用help(filter)得到:

filter(function or None, iterable) –> filter object | | Return
an iterator yielding those items of iterable for which function(item)
is true. If function is None, return the items that are true
ite

(註釋 iterable:在Python裡iterable被認為是一類物件,這類物件能夠一次返回它的一個成員(也就是元素)。抽象一點就是適合迭代的物件)
因為是返回可迭代物件,所以最後要用之前學過的list(),tuple()隨便一個轉換可迭代物件

當引數為(None,iterable)時,示例1:

>>> filter(None,[0,1,3,True,False])
<filter object at 0x041A6230>
>>> list(filter(None,[0,1,3,True,False]))
[1, 3, True]
>>> 

當引數為(function,iterable)時,示例2:

>>> def odd(x):
    return x%2

>>> temp=range(10)
>>> show=filter(odd,temp)
>>> list(show)
[1, 3, 5, 7, 9]

用lambda表示式簡化示例2:

>>> list(filter(lambda x:x%2,range(10)))#用lambda表示式簡化程式碼
[1, 3, 5, 7, 9]
>>> 

3.map()——實現對映

直接看程式碼:

>>> list(map(lambda x:x%2,range(10)))
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
>>> list(map(lambda x:x*2,range(10)))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> 

同樣返回可迭代物件,所以還要轉換的

明天繼續,blog會持續更新^_^。