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

  • 2019 年 10 月 7 日
  • 筆記

什麼是函數

函數就是有特定功能的工具 # 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 就是沒有返回值

# 函數返回值的五種情況(出於演示,就不注重函數前後空行的標準了)  # 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()

小推理

'''  所有的函數都有返回值,無論你寫不寫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 函數的返回值  """

Tags: