1. 程式人生 > >Python - 函式基礎概念 - 三種形式、引數、巢狀、名稱空間

Python - 函式基礎概念 - 三種形式、引數、巢狀、名稱空間

目錄

一、函式的三種形式

1-1 語句形式 - foo()

1-2 表示式形式 - 3*len('hello')

1-3 引數形式 - range(len('hello'))

二、 形參 and 實參

2-1 位置引數 - 實參和形參位置上一一對應,不可多值 、少值

2-2 關鍵詞引數 - 形參實參指定變數名,以關鍵詞辨認位置

2-3 預設形參 -設定預設值的關鍵詞引數,傳值時可省略傳入過程,以預設值替代

2-4 可變長引數 - 實參值的個數不固定

2-4-1 按位置的可變長引數 -- *args

2-4-2 按關鍵詞的可變長引數 -- **kwargs

2-4-3  將傳給一個函式的引數 原封不動的傳給另一個函式 -- *args + **kwargs

2-5 命名關鍵詞引數 - *後定義的引數,必須被傳值(有預設值的除外)

2-6 練習

2-6-1   函式當做另一個函式返回值返回

2-6-2 購物車功能優化選擇

三、函式的巢狀

3-1 函式的巢狀呼叫 - 在呼叫一個函式過程中,其內部程式碼又呼叫了其他函式

3-2 函式的巢狀定義 - 一個函式內部又定義了另外一個函式

四、名稱空間 - 內建、全域性、區域性

4-1 概念

4-2 查詢順序


一、函式的三種形式

1-1 語句形式 - foo()

def foo() :
    print('a')
    return 1
foo()

1-2 表示式形式 - 3*len('hello')

def foo():
    print('a')
    return 1
print(len(foo()))

1-3 引數形式 - range(len('hello'))

def foo1(a):
    print(a)
    return a

def foo2():
    print('a')
    return '123'

print(foo1(foo2()))

二、 形參 and 實參

2-1 位置引數 - 實參和形參位置上一一對應,不可多值 、少值

def func1(x,y):
    print(x,y)

func1(1,2)

2-2 關鍵詞引數 - 形參實參指定變數名,以關鍵詞辨認位置

注意:

  •  實參傳入時可結合位置引數 和 關鍵詞引數 但格式只能為(位置引數,關鍵詞引數),二者位置不可對調
  •  實參不可對同一個值進行重複傳值
def func1(name,age):
    print(name,age)

func1('lin',age = 18)

open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):
open('a.txt','w',encoding='utf-8')

2-3 預設形參 -設定預設值的關鍵詞引數,傳值時可省略傳入過程,以預設值替代

def func1(name,age,sex = 'male'):
    print(name,age,sex)

func1('lin',age = 18)
func1('lin',18,sex='female')

2-4 可變長引數 - 實參值的個數不固定

2-4-1 按位置的可變長引數 -- *args

def foo(x,y,*args):
    print(x,y)
    print(args)

foo(1,2,3,4,5)

# 在實參中帶*:使其打散成位置實參進行賦值
def foo(x,y,*args):
    print(x,y)
    print(args)
foo(1,2,*[3,4,5]) #== foo(1,2,3,4,5,6)


2-4-2 按關鍵詞的可變長引數 -- **kwargs

def foo(x,y,z):
    print(x,y,z)
foo(*[1,2,3])#== foo(1,2,3)

def foo(x,y,**kwargs):
    print(x,y)
    print(kwargs)
foo(1,y=2,a=1,b=2,c=3)

# 在實參中帶**:使其打散成關鍵詞實參進行賦值
def foo(x,y,**kwargs):
    print(x,y)
    print(kwargs)
foo(1,y=2,**{'a':1,'b':2,'c':3})


def foo(x,y,**z):
    print(x,y,z)
foo(**{'z':1,'x':2,'y':3,'a':4})

2-4-3  將傳給一個函式的引數 原封不動的傳給另一個函式 -- *args + **kwargs

# 注:需要遵循foo 函式的規則
def foo(x,y):
    print(x,y)

def wrapper(*args,**kwargs):
    print('====>')
    foo(*args,**kwargs)

# wrapper(1,4)
wrapper(1,y=777)

2-5 命名關鍵詞引數 - *後定義的引數,必須被傳值(有預設值的除外)

'''
*後定義的引數,必須被傳值(有預設值的除外),
且必須按照關鍵字實參的形式傳遞可以保證,傳入的引數中一定包含某些關鍵字
'''

def foo(x,y,*args,a=1,b,**kwargs):
    print(x,y)
    print(args)
    print(a)
    print(b)
    print(kwargs)

foo(1,2,3,4,5,b=3,c=4,d=5)

'''
結果:
    1
    2
    (3, 4, 5)
    1
    3
    {'c': 4, 'd': 5}
    
'''

2-6 練習

2-6-1   函式當做另一個函式返回值返回

def func2(a):
    pass


def func1(a):
    print(a)
    return a


print(func1(func2(3)))

2-6-2 購物車功能優化選擇

def login():
    print('login')

def register():
    print('register')

def shopping():
    print('shopping')

def pay():
    print('pay')


def transfer():
    print('transfer')

func_dic={
    '1':login,
    '2':register,
    '3':shopping,
    '4':pay,
    '5':transfer
}
# print(func_dic)

msg="""
0 退出
1 登陸
2 註冊
3 購物
4 支付
5 轉賬
"""

while True:
    print(msg)
    choice=input('請輸入您的操作: ').strip()
    if choice == '0':break
    if choice in func_dic:
        func_dic[choice]()
    else:
        print('輸入錯誤指令,請重新輸入')

三、函式的巢狀

3-1 函式的巢狀呼叫 - 在呼叫一個函式過程中,其內部程式碼又呼叫了其他函式

def bar():
    print('from bar')

def foo():
    print('from foo')
    bar()

foo()

def max2(x,y):
    if x > y:
        return x
    else:
        return y

def max4(a,b,c,d):
    res1=max2(a,b)
    res2=max2(res1,c)
    res3=max2(res2,d)
    return res3

print(max4(1,2,3,4))

3-2 函式的巢狀定義 - 一個函式內部又定義了另外一個函式

def outter():
    x=1
    print('from outter')
    def inner():
        print('from inner')
    # print(x)
    # print(inner)
    inner()

# outter()
# inner

outter()

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

f1()

from math import pi
# print(pi)

def circle(radius,action=0):
    """
       圓形相關運算
       :param radius: 半徑
       :param action: 0代表求面積,1代表求周長
       :return: 面積或者周長
       """

    def area(radius):
        return pi * (radius ** 2)

    def perimiter(radius):
        return 2 * pi * radius

    if action == 0:
        res=area(radius)
    elif action == 1:
        res=perimiter(radius)

    return res


print(circle(10,0))
print(circle(10,1))

四、名稱空間 - 內建、全域性、區域性

4-1 概念

'''

名稱空間:存放名字的地方,存在三種名稱空間。

#1、python直譯器先啟動,因而首先載入的是:內建名稱空間
#2、執行test.py檔案,然後以檔案為基礎,載入全域性名稱空間
#3、在執行檔案的過程中如果呼叫函式,則臨時產生區域性名稱空間

- 問題:x=1,1存放於記憶體中,那名字x存放在哪裡呢?
    名稱空間正是存放名字x與1繫結關係的地方
'''

 # cmd 終端下 執行檔案 -python test.py

len=111

def foo():
    len=222
    print('站在區域性找len: ',len)

foo()
print('站在全域性找len: ',len)

4-2 查詢順序

# 名字的查詢順序,在函式定義階段已經固定,與函式呼叫位置無關
# 即:無論在任何地方呼叫函式,都必須回到當初定義的函式位置進行查詢區域性或者全域性變數
x = 111


def outer():
    def inner():
        print('from inner', x)  # x訪問的時全域性名稱空間中x

    return inner


f = outer()
# print(f)

x = 222
f()

'''
LEGB 代表名字查詢順序:
 locals -> enclosing function -> globals -> __builtins__
locals 是函式內的名字空間,包括區域性變數和形參
      locals() 函式會以字典型別返回當前位置的全部區域性變數。
enclosing 外部巢狀函式的名字空間(閉包中常見)
globals 全域性變數,函式定義所在模組的名字空間
         global 在區域性中宣告來自全域性作用域的變數名字,可以用來改變全域性變數的值
builtins 內建模組的名字空間
nonlocal 函式宣告一個名字是來自於當前外一層作用域的名字,用來修改外層函式的變數值

locals()
>>>def runoob(arg):    # 兩個區域性變數:arg、z
...     z = 1
...     print (locals())
...
>>> runoob(4)
{'z': 1, 'arg': 4}      # 返回一個名字/值對的字典
>>> globals

x=1
def foo():
    x=2
foo()
print(x)

x=1
def foo():
    global x
    x=2
foo()
print(x)

nonlocal 函式宣告一個名字是來自於當前外一層作用域的名字,用來修改外層函式的變數值
'''

x = 0


def f1():
    x = 111

    def f2():
        nonlocal x
        x = 222

    f2()
    print(x)


f1()
print()