day-11

1. 可變長參數

1.1 可變長參數之形參

1.1.1 *形參名

def f1(*args):  # *args(默認的寫法)用元組接收多餘的位置實參
    print(args)
    
f1()    # 不傳參數
f1(1)   # 傳一個
f1(1, 2, 3, 4, 5)   #傳多個

運行結果:app

# 多餘的變量值使用元組存儲
()          
(1,)
(1, 2, 3, 4, 5)

Process finished with exit code 0

1.1.2 **形參

def f1(**kwargs):   # **kwargs(默認的寫法)用字典接收多餘的關鍵字實參,將字典的值賦給參數
    print(kwargs)


f1()
f1(x=1)
f1(x=1, y=2)

運行結果:函數

# 多餘的變量值使用字典存儲
{}  # 不傳參數
{'x': 1}    # 傳一個
{'x': 1, 'y': 2}    # 傳多個

Process finished with exit code 0

1.2 可變長參數之實參(瞭解)

1.2.1 *實參

def f1(a, b, c, e, d, f, g):
    print(a, b, c, e, d, f, g)


lt = [1, 2, 3, 4, 5, 6, 7]
f1(*lt)     # * 把列表中的元素打散成位置實參依次傳給位置形參

運行結果:ui

1 2 3 4 5 6 7

Process finished with exit code 0

1.2.1 **實參

def f1(a, b):
    print(a, b)


dic = {'a': 1, 'b': 2}  # a = 1,b = 2
f1(**dic)  # **dic把字典打散成關鍵字實參而後傳給函數f1

運行結果:code

1 2

Process finished with exit code 0

2. 函數對象

python中一切皆對象對象

對象的四大功能:內存

  1. 引用
  2. 用做容器元素
  3. 做爲函數的實參
  4. 看成函數的返回值

函數的對象

函數的對象 == 函數名作用域

def f1():   # 定義一個函數 f1(),函數對象是 f1
    print('from f1')

1. 函數對象的引用

func = f1   # func 引用函數對象 f1 ,則 func 也具備了函數的功能
print('f1:', f1)
print('func:', func)
func()

運行結果:it

f1: <function f1 at 0x0000019477EB34C8>
func: <function f1 at 0x0000019477EB34C8>
# f1 和 func 指向的內存地址是相同的    
from f1 # 運行了函數 f1

Process finished with exit code 0

2. 看成容器類元素

lt = [f1, 1, 2, 3]  # 將函數對象看成容器類元素

print('lt[0]:', lt[0])  # 取出列表內的第一個元素
print('f1:', f1)    # 打印 f1 的內存地址

lt[0]() # lt[0] 取出了函數對象,加上()直接調用函數

運行結果:io

lt[0]: <function f1 at 0x0000025308EB34C8>
f1: <function f1 at 0x0000025308EB34C8>
# f1 和 lt[0] 指向的內存地址是相同的  
from f1 # 運行了 f1 函數

Process finished with exit code 0

3. 做爲函數的實參

def f2(f2_f1):
    print('f2_f1', f2_f1)
    f2_f1()


print('f1', f1)
f2(f1)

運行結果:

f2_f1 <function f1 at 0x0000022D6C343798>
from f1
f1 <function f1 at 0x0000022D6C343798>

4. 看成函數的返回值

def f2(f2_f1):
    return f2_f1


res = f2(f1)
print('res', res)
print('f1', f1)

res()

運行結果:

res <function f1 at 0x000001F93C5E3798>
f1 <function f1 at 0x000001F93C5E3798>
from f1

Process finished with exit code 0

3. 函數的嵌套

函數裏面再定義函數。

  • 函數的嵌套
# 定義函數,只檢測語法,不會執行代碼
def f1():
    print('from f1')

    def f2():
        print('from f2')
  • 函數的嵌套調用

    函數內部定義的函數,外部不能使用

def f1():
    print('from f1')

    def f2():
        print('from f2')
        
res = f1()

運行結果:

from f1

Process finished with exit code 0

4. 名稱空間和做用域

4.1 名稱空間

內存中存儲變量名與變量之間綁定關係的空間。

4.1.1 內置名稱空間

存放 python 解釋器自帶的內置方法的名字,如: int float print def ……

4.1.1 局部名稱空間

用於存放函數調用期間函數體產生的名字,即存放函數內部定義的變量名的空間。

以下面的: xf2

def f1():
    x = 10
    def f2():
        z = 20

4.1.1 全局名稱空間

除了內置名稱空間和局部名稱空間外,其餘全部的名稱都存放再全局名稱空間。

以下面的: xfunclt

x = 1

def func():
    pass

lt = [1, 2]

4.1.1 加載順序

內置名稱空間>>>全局名稱空間>>>局部名稱空間

python解釋器加載完內置名稱空間後才能打開文件,打開文件後會產生全局名稱空間,當文件內的某個函數被調用,再產生局部名稱空間。

4.1.1 查找順序

當前所在的空間查找>>>局部名稱空間查找>>>全局名稱空間查找>>>內置名稱空間查找>>>報錯

# 這裏使用關鍵字看成變量名,是爲了演示查找順序,實際使用不要這樣命名

# 1
len  =10

def f1():
    len = 20

    print('1:', len)    #先查找當前名稱空間,即查找局部名稱空間找到爲:20

f1()

# 2
len  =10

def f1():
    print('2:', len)    #當前局部名稱空間查找不到,查找全局名稱空間找到爲:10

f1()

# 3
def f1():
    print('3:', len)    #當前局部全局名稱空間都查找不到,查找內置名稱空間:找到內置函數 len

f1()

運行結果:

# 1
1:20
# 2
2:10
# 3
3:<built-in function len>

Process finished with exit code 0

4.2 做用域

4.2.1 全局做用域

全局做用域包括內置名稱空間和全局名稱空間。

全局做用域的變量 x 和局部做用域的變量 x 沒有任何關係。

y = 10  # 定義一個變量 y

def f1():   # 定義一個函數 f1 ,做用是讓 y = 2
    y = 2   


f1()    # 調用函數,是函數生效

print(y)    # 打印 y

運行結果:

10  # y = 10,局部做用域的變量 y 並無被全局做用域的變量 y 影響

Process finished with exit code 0

4.2.2 局部做用域

局部做用域只包含局部名稱空間。

局部做用域1的 x 和局部做用域2的 x 沒有任何關係,即使他們處於同一個局部做用域下。

# 函數 f2 和 f3 同屬於一個局部做用域下
def f1():
    def f2():
        def f3():   
            x = 1   
            print(x) # 打印 f3 局部做用域下的 x = 1

        x = 2   # 讓 f2 局部做用域下的 x = 2
        f3()

    f2()

f1()    # 調用函數 f1

運行結果:

1   # 局部做用域 f3 下的變量 x 並無被局部做用域 f2 下的 x 影響

Process finished with exit code 0

4.3 補充

4.3.1 globalnonlocal (儘可能不要使用)

  • global

    global 如下的局部做用域的變量變成全局做用域的變量

    不使用global

    x = 10
    
    def f1():
        # global x  # 讓global如下的局部的x變成全局的x
        x = 20
    
    
    f1()
    print(x)

    運行結果:

    10
    
    Process finished with exit code 0

    使用global 後:

    20
    
    Process finished with exit code 0
  • nonlocal

    nonlocal 讓變量成爲頂層函數的局部做用域的變量,注意不是成爲全局做用域的變量(沒有應用情景,生產中儘可能不要嵌套函數)

    不使用nonlocal

    def f1():
        def f2():
            def f3():
                # nonlocal x  # nonlocal讓x成爲頂層函數的局部
                x = 1
    
            x = 2
            f3()
            print(x)
    
        f2()
    
    f1()

    運行結果:

    2
    
    Process finished with exit code 0

    使用nonlocal 後:

    def f1():
        def f2():
            def f3():
                nonlocal x  # nonlocal讓x成爲頂層函數的局部
                x = 1
    
            x = 2
            f3()
            print(x)
    
        f2()
    
    f1()

    運行結果:

    1
    
    Process finished with exit code 0

4.3.2 全部可變數據類型都可打破上述一切規則

lt = [0]
def f1():   # 局部做用域內接收了全局做用域定義的變量 lt ,而且改變了 全局做用域下的 lt 的內容,
    lt.append(1)    # 1.向列表添加值
    lt[0] = 1       # 2. 更改列表第一個值


f1()
print(lt)

運行結果:

[0, 1]  # 1.
[1, 1]  # 2.
相關文章
相關標籤/搜索