Python函數、參數及參數解構

Python函數、參數及參數解構

函數

  • 數學定義:y=f(x),y是x的函數,x是自變量
  • Python函數
    1. 由若干語句塊組成的語句塊、函數名稱、參數列表構成,他是組織代碼的最小單元
    2. 完成一定的功能
  • 函數的作用
    1. 結構化編程對代碼的最基本的封裝,一般按照功能組織一段代碼
    2. 封裝的目的是為了復用,減少冗余代碼
    3. 代碼更加簡潔美觀、可讀易懂
  • 函數的分類
    1. 內建函數,如max()、min()
    2. 庫函數,如math.ceil

函數的定義、調用

  • def語句定義函數
    def 函數名(參數列表):
        代碼塊          #函數體
        [return 返回值]
    
    1. 函數名就是標識符,命名要求和標識符命名要求一致
    2. 語句塊必須縮進,約定四個空格
    3. Python的函數沒有return語句,隱式會返回一個None值
    4. 定義中的參數列表稱為形式參數,只使一種符號表達,簡稱形參
  • 調用
    1. 函數定義,只是聲明了一個函數,他不會被執行,需要調用
    2. 調用的方式,就是函數名加上小括號,括號內寫上參數
    3. 調用時寫的參數是實際參數,是傳入給函數的值,簡稱參數
  • 函數舉例
    def add(x,y):
        result = x + y
        return result
    out = add(4,5)
    print(out)
    1. 定義需要在調用前,也就是說調用時已經被定義過了,否則報錯name is not defined
    2. 函數是可調用的對象,zaipython中有個內建函數callable() 可以查看標識符是否是一個可調用的對象
  • 函數參數
    1. 參數調用時傳入的參數要和定義的參數個數相匹配(可變參數例外)
    2. 位置參數
      • def f(x,y,z) 調用使用f(1,3,5)
      • 按照參數定義順序傳入實參
    3. 關鍵字參數
      • def f(x,y,z) 調用使用f(x=1,y=3,z=5)
      • 使用形參的名字來傳入實參的方式,如果使用了形參名字,那么傳參順序就可以和定義順序不同
    4. 傳參
      • f(z=None,y=10,x=[1])
      • f((1,),z=6,y=4.1)
      • f(y=5,z=6,2)
      • 要求位置參數必須在關鍵字參數之前傳參,位置參數是按位置對應的
  • 函數參數默認值
    1. 參數默認值
      定義時,在形參后跟上一個值
      def add(x=4,y=5):
          return x+y
      測試調用: add(6,10)、add(6,y=7)、add(y=7)、add(x=5,6)、add(y=8,4)、add(x=5,y=6)、add(y=5,x=6)
      測試 def add(x=4,y)
    2. 作用
      • 參數的默認值可以在未傳入足夠的實參的時候,對沒有給定的參數賦值為默認值
      • 參數非常多的時候,并不需要用戶每次都輸入所有參數,簡化函數調用
    3. 舉例:定義一個函數login,參數名host、port、username、password
      def login(host='127.0.0.1',port='3306',username='kx',password='7954321'):
          print('{}:{}@{}/{}'.format(host,port,username,password))
      
      測試調用
      login()
      login('127.0.0.1',80,'stephon','stephon')
      login('127.0.0.1',username='root')
      login('localhost',port=80,password='com')
      login(port=80,password='7954321',host='www')
  • 可變參數
    1. 問題:有多個數需要累加求和
      def add(nums):
          sum = 0
          for x in nums:
              sum += x
          return sum
      測試調用 add([1,3,5])、add((2,5,8))
      
      ==傳入迭代元素,迭代元素求和==
    2. 可變參數:一個形參可以匹配任意個參數
    3. 位置參數的可變參數
      有多個數,需要累加求和
      
      def add(*nums):
          sum = 0
          print(nums)
          for x in nums:
              sum += x
          print(sum)
          
      測試調用add(3,6,9)
    4. 在形參前使用*標識改形參時可變參數,可以接受多個實參
    5. 收集多個實參為一個tuple
  • 關鍵字參數的可變參數
    1. 關鍵字參數的可變參數
      例子:  配置信息打印
      def shouconfig(**kwargs):
          for k,v in kwargs.items():
              print('{}={}'.format(k,v))
      測試調用
    2. 形參前使用**符號,標識可以接受多個關鍵字參數
    3. 收集的實參名稱和值組成一個字典
  • 可變參數混合使用
    - def showconfig(username,password,**kwargs)
    - def showcofig(username,*args,**kwargs)
    - def showconfig(username,password,**kwargs,*args)
  • 總結
    1. 有位置可變參數和關鍵字可變參數
    2. 位置可變參數和關鍵字可變參數都可以收集若干個實參,位置可變參數手機實參形成元組,關鍵字可變參數收集實參形成一個字典
    3. 混合使用參數的時候,可變參數要放在參數列表最后,普通參數放在參數列表前面,位置可變參數需要放在關鍵字參數之前
  • keyword-only參數(python3版本中加入)
    • 如果一個星號參數后,或者一個位置可變參數后,出現的普通參數,實際上已經不是普通參數了,而是keyword-only參數
    def fn(*args,x):
        print(x)
        print(args)
    
    測試調用fn(3,5)、fn(3,5,7)、fn(3,5,x=7)
    
    args可以看作已經截獲了所有的位置參數,x不使用關鍵字參數就拿不到實參
    • 當一個可變關鍵字參數后面有普通參數時,因為可變關鍵字參數本省就會收集所有的關鍵字參數的,這樣就失去了意義,所以會直接報語法錯誤
    • keyword-only參數的另一種形式
    def fn(*,x,y):
        print(x,y)
    
    測試調用發現
    *號之后,普通形參都變成了必須給出的keyword-only參數
  • 可變參數和參數默認值
    1. 參數列表參數規則:一般順序是普通參數、缺省參數、可變位置參數、keyword-only參數(可帶默認值)、可變關鍵字參數
    2. 注意
      • 代碼應該易讀易懂
      • 請按照哦書寫習慣定義函數參數

參數解構

  • 參數解構
    1. 給函數提供參數的時候,可以在集合類型前使用或者*,把集合類型的結構解開,提取所有的元素作為函數的參數
    2. 非字典類型使用*解構成位置參數
    3. 字典類型使用**解構成關鍵字參數
    4. 提取出的元素數目要和參數的要求匹配,也要和參數的類型匹配
  • 參數解構和可變參數
    • 在給函數提供實參的時候,可以在集合類型前使用或者*,把集合類型的結構解開,提取出所有的元素作為函數的實參
    def add(*args):
        result = 0
        for x in args:
            result += x
        return result
        
    測試調用

練習

  • 編寫一個函數,能夠接受至少兩個參數,返回最小值和最大值
    In [6]: def fn(*targ):
       ...:     return min(targ),max(targ)
    
    In [7]: fn(1,2,4,2,7)  #或者可以導入romdom模塊,生成列表作為函數參數
    Out[7]: (1, 7)
  • 編寫一個函數,接受一個參數n,n為正整數,打印出如下兩種樣式,要求數字需要對齊
1               
               2 1                  
             3 2 1      
           4 3 2 1      
         5 4 3 2 1      
       6 5 4 3 2 1      
     7 6 5 4 3 2 1  
   8 7 6 5 4 3 2 1  
 9 8 7 6 5 4 3 2 1  
 


 9 8 7 6 5 4 3 2 1
   8 7 6 5 4 3 2 1
     7 6 5 4 3 2 1
       6 5 4 3 2 1
         5 4 3 2 1
           4 3 2 1
             3 2 1
               2 1
                 1
def fn1(n):
    tail = ' '.join([str(i) for i in range(n,0,-1)])
    width = len(tail)
    for i in range(1,n):
        print('{:>{}}'.format(' '.join([str(j) for j in range(i,0,-1)]),width))
    print(tail)
----------------------------------------------------------
def f1(n):
    for i in range(1,n+1):
        print(' '.join([' '*(len(str(n)))]*(n-i)+[' '*(len(str(n))-len(str(j)))+str(j) for j in range(i,0,-1)]))
------------------------------------------------------------------------------
def fnl(n):
    for i in range(1,n+1):
        for j in range(n,0,-1):
            if i < j:
                print(' '*len(str(j)),end=' ')
            else:
                print(j,end=' ')
        print()
        
2. 

def fn2(n):
    tail = ' '.join([str(i) for i in range(n,0,-1)])
    print(tail)
    for i in range(len(tail)):
        if tail[i] == ' ':
            print(' '*i, tail[i+1:])
-------------------------------------------------
def fnl(n):
    for i in range(n,0,-1):
        for j in range(n,0,-1):
            if i < j:
                print(' '*len(str(j)),end=' ')
            else:
                print(j,end=' ')
        print()

上下合在一起

def fnl(n):
    for i in range(-n,n+1):
        if i<0:
            for j in range(n,0,-1):
                if -i < j:
                    print(' '*len(str(j)),end=' ')
                else:
                    print(j,end=' ')
            print()
        elif i == 0:
            pass
        else:
            for j in range(n,0,-1):
                if i < j:
                    print(' '*len(str(j)),end=' ')
                else:
                    print(j,end=' ')
            print()

函數返回值

  • 返回值總結
    1. Python函數使用return語句返回‘返回值’
    2. 所有函數都有返回值,如果沒有return語句隱式調用return None
    3. return語句并不一定是函數的語句塊的最后一條語句
    4. 一個函數可以存在多個return語句,但是只有一條可以被執行。如果沒有一條return語句被執行到,就隱式調用return None
    5. 如果有必要可以顯示調用return None,可以簡寫為return
    6. 如果函數執行了return語句,函數就會返回,當前被執行的return語句之后的其他語句就不會被執行了
    7. 作用:結束函數調用,返回值
    8. 函數不能同時返回多個值
      • return [1,2,5] 是指明返回一個列表,是一個列表對象
      • return 1,2,5 看似返回多個值,實際上是飲食的被python封裝成了一個元組
  • 函數嵌套
    1. 在一個函數中定義了另外一個函數
    2. 函數有可見范圍,這就是作用域的概念
    3. 內部函數不能被外部直接使用,會報nameerror

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/87819

(0)
KX_ilKX_il
上一篇 2017-10-15 22:15
下一篇 2017-10-16 09:41

相關推薦

  • 序列化 Json MessagePack

    序列化 反序列化 pickle模塊
    Json 模塊
    MessagePack

    2018-05-02
  • Python文件操作

    計算機體系架構 運算器:完成各種算術運算、邏輯運算、出具傳輸等數據加工處理 控制器:控制程序的執行 CPU = 運算器 + 控制器 存儲器:用于記憶程序的數據,內存 輸入設備:將數據或程序輸入到計算機中 輸出設備:將數據或程序的處理結果展示給用戶 文件IO常用操作 open 打開 read 讀取 write 寫入 close 關閉 readline 行讀取 …

    Python筆記 2018-05-02
  • Python第十二周學習總結

    并行,并發,多線程

    2018-05-27
  • Python函數式編程指南(二):函數

    這是此系列的第二篇,試圖說明在Python中如何更好地使用函數并引導諸位使用函數式的思維進行思考。掌握并應用這些內容,就已經是至少形似的函數式風格的代碼了,至于思維么,這個真靠自己。 作者水平有限,如有錯漏之處還請指出;轉載請注明原作者和原地址:) 2. 從函數開始 2.1. 定義一個函數 如下定義了一個求和函數: def add(x, y): return…

    Linux干貨 2015-03-11
  • 選擇排序 以及 set、dict、習題練習

    習題練習 僅作參考

    2017-10-10
  • 文件操作

    文件操作 馮諾依曼體系架構 CPU由運算器和控制器組成 運算器,完成各種算數的運算,邏輯運算,數據傳輸等數據加工處理 控制器,控制程序的執行 存儲器,用于記憶程序的數據,列如內存 輸入設備,將數據或者程序輸入到計算機中列如鍵盤 鼠標 輸出設備,將數據或者程序的處理結果展示給用戶,列如顯示器,打印機等等 ? 一般說的IO操作,指的是文件的IO,如果是指網絡的I…

    Python筆記 2018-05-02
欧美性久久久久