python函數基礎-參數-返回值-注釋-01


什么是函數

函數就是有特定功能的工具 # python中有內置函數(python解釋器預先封裝好的)與自定義函數(用戶自定義封裝的)之分 

為什么要用函數

# 可以減少代碼冗余,增加代碼復用性
# 使代碼邏輯更加清晰
# 一次編寫,任意次數調用

函數定義

'''
精簡版定義:
def 函數名():
    代碼體

調用:
函數名()
'''

函數名命名規范 # 函數名的命名規則與變量名的一模一樣 ,千萬注意兩點 # 不能以關鍵字作為函數名,避免與內置函數重名(比如內置函數 len)(******) , # 函數也應該做到見名知意 

函數的定義及執行順序

注意點

'''
函數在定義階段只檢測語法,不執行代碼
    比如里面寫多了一個 if  后面就沒了,運行就會報錯
    執行的時候,代碼有問題才會報錯了

變量可以通過變量名找到對應的值
函數可以通過 函數名 加 括號 找到函數體所對應的的代碼並執行

函數必須先定義后調用(函數名+括號)
定義了之后的函數可以在任意位置調用
'''

函數的一種特殊應用

空函數: 在項目的初期應用頻率非常高,可以快速構建項目框架,使項目架構與進度清晰明了(還有幾個功能(pass)沒寫) 

# 可以直接羅列出功能名,也可以給出一些參數
def register():
    pass


def login():
    pass


def print_shop_list():
    pass


def choice_shop():
    pass


def pay():
    pass

return關鍵字

 # 函數要想返回給調用者一個值,就必須使用return 關鍵字 

函數返回值 # 測試函數有無返回值可用變量接收,None 其實也是一種特殊的返回值 

# 函數返回值的五種情況(出於演示,就不注重函數前后空行的代碼標准(PEP8規范)了)
# 1.不寫return
def func_no_return():
    print(1, 2, 3)
print(func_no_return())  # 接收到的是None
# 1 2 3
# None

# 2.return后面什么也不跟
def func_just_return():
    print(1, 2, 3)
    return
    print("hello world.")  # 這一句print 並未被執行
print(func_just_return())  # 接收到的是None
# 1 2 3
# None

# 3.寫return None
def func_return_none():
    print(1, 2, 3)
    return None
print(func_return_none())  # 接收到的是None
# 1 2 3
# None

# 4.寫return 返回一個值
def func_return_one():
    print(1, 2, 3)
    return 1
print(func_return_one())  # 接收到的是返回值 1, 這個值可以是python的任意數據類型
# 1 2 3
# 1

# 5.寫return多個值
def func_return_many():
    print(1, 2, 3)
    return 1, 2, 3
print(func_return_many())  # 接收到的是一個元組,包裹上這三個元素,想要多個返回值不被包裝成元組返回,可以選擇將其整體包裝成一個大類型(例如列表,最外層在套一個列表 [[1,2,3]. [1,2,3]])
# 1 2 3
# (1, 2, 3)

利用return 關鍵字可直接結束函數 # 某些場景比break還要好用些 

# return除了可以返回值之外,還可以直接結束當前所在函數整個函數的運行,而無需像break一樣,一層一層結束
def hi():
    while True:
        name = input("what your name? >>>:")
        if name:
            print('hi, name! nice to meet you!')
        else:
            continue
        while True:
            age = input("how old are you? >>>:")
            if age:
                print(f"oh, it hard to see that you are {age} years old!")
            else:
                continue
            while True:
                hobby = input("what's your hobby? >>>:")
                if hobby:
                    print(f'you like {hobby}, it seems so cool.')
                    return  # 執行到這里,hi() 這個函數就直接結束了


hi()

小推理

'''
所有的函數都有返回值,無論你寫不寫return
    python中,不寫返回值默認返回None,其實也算返回值
只寫return或者return None 並不是為了考慮返回值的問題,而是為了結束函數的運行
'''

函數的參數

形參: # 在函數定義階段,函數的括號內寫的變量名,叫做該函數的形式參數,簡稱形參 

實參: # 在函數調用階段,括號內實際傳入的值,叫做實際參數,簡稱實參 

形參與實參的關系: # 形參就相當於變量名,而實參相當於變量的值,函數調用傳參的過程就是給形參、變量名賦值的過程 

注意點: # 實參和形參的綁定關系只在函數的運行階段有效,函數運行結束后自動解除 # 只在函數內部有效,函數外部無任何影響 

兩種傳參方式

# 位置形參:在函數定義階段按照位置從左往右依次書寫的變量名
def my_max(x, y):
    print(x, y)
    if x > y:
        return x
    else:
        return y
# res = my_max(1)  # 會報錯,在調用函數的時候 少一個實參不行
# res = my_max(1, 2, 3)  # 會報錯,在調用函數的時候 多一個實參也不行


# 第一種直接按照位置傳  一一對應
res = my_max(20, 10)
# 20 10
# 位置實參:在函數的調用階段 傳入的參數會按照位置一一對應給形參

# 第二種指名道姓的傳  >>>:關鍵字傳參
my_max(y=20, x=10)
my_max(10, y=20)  # 位置和關鍵字混合使用
my_max(20, y=40)
# 10 20
# 10 20
# 20 40

注意點:

"""
注意:在函數的調用階段 位置參數和關鍵字參數可以混合使用
但是必須保證
    1.位置參數必須在關鍵字參數的前面(越短的越靠前,越長的越復雜的越靠后)
    2.同一個形參不能被多次賦值
"""

默認值參數

默認值參數: # 在函數的定義階段,形參(變量名)就已經被賦值了的參數 , def my_max(x,y=100): # 這里的y 就是一個默認值參數 

def my_max(x, y=100):
    if x > y:
        return x
    return y
print(my_max(200))  # 這里沒有傳入默認參數y, y 等於 默認值函數定義時的 100,y = 100
print(my_max(200, 1000))  # 這里傳入了默認參數y, y 等於 傳入的 1000,y = 1000
print(my_max(y=200, x=1000))  # 這里使用關鍵字傳參,傳了 y = 200, y = 200
# 200
# 1000
# 1000

'''
# 在調用的時候可以不為默認值形參傳值,默認使用定義階段就已經綁定的值
# 在調用的時候如果可以給默認值形參傳值 傳了那么就使用你傳的值
# 在定義階段 默認值形參必須放在位置形參的后面
'''

默認值參數的應用場景(例如錄入信息時的性別)

student_infos = []
def record_student_info(student_name, student_age, student_gender='male'):
    student = dict(name=student_name, age=student_age, gender=student_gender)
    student_infos.append(student)

while True:
    student_name = input("請輸入您的姓名>>>:").strip()
    student_age = input("請輸入您的年齡>>>:").strip()
    student_gender = input("請輸入您的性別>>>:").strip()
    if student_gender == 'female':
        record_student_info(student_name, student_age, student_gender)
    else:
        record_student_info(student_name, student_age)
    print(student_infos)

默認值傳參面試可能會考到

# 這里的問題是共用了同一個列表(畫一張列表的變量關系引用圖就知道了)
def info(username,hobby,l=[]):
    l.append(hobby)
    print('%s 的愛好是 %s'%(username,l))
info('jason','study')
info('tank','生蚝')
info('kevin','喝腰子湯')
info('egon','女教練')
# jason 的愛好是 ['study']
# tank 的愛好是 ['study', '生蚝']
# kevin 的愛好是 ['study', '生蚝', '喝腰子湯']
# egon 的愛好是 ['study', '生蚝', '喝腰子湯', '女教練']

# 解決方法1,每次傳一個空列表過去
info('jason','study',[])
info('tank','生蚝',[])
info('kevin','喝腰子湯',[])
info('egon','女教練',[])
# jason 的愛好是 ['study']
# tank 的愛好是 ['生蚝']
# kevin 的愛好是 ['喝腰子湯']
# egon 的愛好是 ['女教練']

# 解決方法2,改寫函數默認參數,沒傳就重新申請一個空列表
def info(username,hobby,l=None):
    if l == None:
        l = []
    l.append(hobby)
    print('%s 的愛好是 %s'%(username,l))

info('jason','study')
info('tank','生蚝')
info('kevin','喝腰子湯')
info('egon','女教練')
# jason 的愛好是 ['study']
# tank 的愛好是 ['生蚝']
# kevin 的愛好是 ['喝腰子湯']
# egon 的愛好是 ['女教練']

易錯點**** # 函數在定義階段 內部所使用的變量都已經初始化完畢了,不會因為調用的位置的變化 而影響到內部的值 

m = 100
def my_max(x, y=m):
    print(x, y)
m = 222
my_max(111)
# 111 100

'''
函數在定義階段 內部所使用的變量都已經初始化完畢了
不會因為調用的位置的變化 而影響到內部的值(暫時可忽略)

函數無論在什么地方被調用
都會跑到函數定義階段去執行代碼
形參中用到的值都是往函數定義階段代碼往上找
'''

可變長參數

# 站在調用函數傳遞實參的角度  實參的個數不固定的情況 也就意味形參也不固定
# 站在形參的角度 可以用*和**來接收多余的(溢出的)位置參數和關鍵字參數

站在形參(函數定義)的角度看 * 、**

  *args # 形參中的*會將多余的(溢出的)位置實參 統一用元組的形式處理 傳遞給* 后面的形參名,* 在形參中只能接受多余的位置實參,不能接受關鍵字實參 

def func(x, y, *z):
    print(x, y, z)  # z = (3, 4, 5, 6, 7, 8, 54, 43, 4, 5, 6, 6, 7, 8)
func(1, 2, 3, 4, 5, 6, 7, 8, 54, 43, 4, 5, 6, 6, 7, 8,)
# 1 2 (3, 4, 5, 6, 7, 8, 54, 43, 4, 5, 6, 6, 7, 8)
# func(1, 2, 1, 3, 4, 5, z=15)  # 報錯,TypeError: func() got an unexpected keyword argument 'z'

  **kwargs # ** 會接收所有多余的關鍵字參數 並將關鍵字參數 轉換成字典的形式 字典的key就是關鍵字的名字,字典的value就是關鍵字的名字指向的值 將字典交給** 后面的變量名 

def func(x, y, **z):
    print(x,y,z)  # 去掉前面關鍵字傳參成功的x, y,將剩下的關鍵字傳參存入z 中, z = {'z': 1, 'a': 1, 'b': 2, 'c': 3}
func(x=1, y=2, z=1, a=1, b=2, c=3)
# 1 2 {'z': 1, 'a': 1, 'b': 2, 'c': 3}

站在實參(函數調用)的角度看 * 、**

  *args # 會將容器類型(列表、元組、集合,字典不能)打散成位置實參一一傳入, * 內部可以看成for 循環 

def func(x,y,z):
    print(x,y,z)
# l = [1,2,3]
# a,b,c = l
# func(a,b,c)
func(*[1,2,3])  # * 會將列表打散成位置實參一一傳入等價於func(1,2,3)
func(*(1,2,3))  # 等價於func(1,2,3)
# 1 2 3
# 1 2 3

def func(x,*z):
    print(x,z)
func(1,*{1,2,3})  # * 在形參中只能接收多余的位置實參 不能接收關鍵字實參
# 1 (1, 2, 3)

  **kwargs # ** 會將字典拆封成key = value的形式,以關鍵字傳參的方式傳值 

def func(x, y, z):
    print(x, y, z)
func(x=1, y=2, z=3)
# 1 2 3
d = {'x': 1, 'y': 2, 'z': 333}
func(**d)  # 等價於func(x=1,y=2,z=333)
# 1 2 333

可接收任意參數的函數

# 需求:你寫的函數 無論調用者按照正確傳參的方式無論怎么傳 你的函數都能夠正常執行
def func1(*x, **y):
    print(x, y)
func1(1, 2, 3, 4, 5, 6, x=1, y=2, z=3)
# (1, 2, 3, 4, 5, 6) {'x': 1, 'y': 2, 'z': 3}

"""
下面是python推薦形參*和**通用的寫法(后面的參數名命名推薦)
"""
def func2(*args, **kwargs):  # 可接收任意參數的函數
    print(args, kwargs)
func2(1, 2, 3, 4, 5, 6, x=1, y=2, z=3)
# (1, 2, 3, 4, 5, 6) {'x': 1, 'y': 2, 'z': 3}

命名關鍵字參數

命名關鍵字參數: # 在函數定義階段,寫在 * 與 ** 之間的參數 

  下面的z 和 m 都是命名關鍵字參數

def func(x, y=1, *args, z=3, m, **kwargs):
    print(x, y)
    print(args)
    print(z, m)
    print(kwargs)


func(1, 2, 3, 4, [5, 6, 7], m=1, z=3, n=1, q=1, p=2)  # 關鍵字傳參 m = 2
# 要想給m傳值, 必須用關鍵字傳值 m = 2,如果直接用位置參數,顯然會被 *args接收(截取)
# 調用 func() 返回值如下:
# 1 2
# (3, 4, [5, 6, 7])
# 3 1
# {'n': 1, 'q': 1, 'p': 2}

注意: # 在給命名關鍵字參數傳值的時候 只能用關鍵字為其傳值 , # 在定義階段 給你感覺好像是z是默認值參數 放在了m這個位置參數的前面了 應該報錯,但其實 z 和 m 都不是默認值參數和位置參數, 他們是命名關鍵字參數 

函數的注釋

函數注釋的好處: # 規范的代碼注釋可以讓封裝的方法被快速讀懂,讓調用者快速上手....(有着諸多好處) 

# 在pycharm 中只需要在函數定義def 關鍵字下一行 敲 ''' 回車即可自動出現函數注釋格式,只需相應填充即可
"""
該函數的作用
:param x: 對形參x的解釋
:param y: 對形參y的解釋
:return: 對函數返回值的解釋
"""

查看寫好的函數注釋: # help(函數名) ,會返回該函數的注釋信息

def say_hi(name):
    '''
    跟用戶打招呼
    :param name: 用戶名
    :return: 拼接好的打招呼語句
    '''
    hi = '{name} 你好,很高興見到你!'.format(name=name)
    return hi


print(help(say_hi))
# Help on function say_hi in module __main__:
# 
# say_hi(name)
#     跟用戶打招呼
#     :param name: 用戶名
#     :return: 拼接好的打招呼語句
# 
# None

上面介紹了函數的return返回值、參數、注釋, 下面給出一個標准的函數定義格式

"""
def 函數名(形參1, ......):
    '''
    該函數的作用(函數的注釋)
    :param 形參1: 對形參1的解釋
    :param .....: .....
    :return: 
    '''
    代碼體
    return 函數的返回值
"""

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM