5、函數

1. 函數定義

函數就是將一些代碼塊封裝到一個特定的容器內,只有須要使用該容器實現特定的功能時,纔會經過調用函數的方式來運行其內部代碼。閉包

def fun(參數):
    函數塊
    return 返回值

1.1 形參

定義函數時的參數。app

  • 位置參數
def fun(name, age, num):
    pass
  • 關鍵字參數
def fun(name = 'aaron', age = 20, num = '201620'):
    pass
  • 注意函數

    • 位置參數和關鍵字參數混合使用時,位置參數必須在關鍵字參數以前。
    def fun(name, age, num = '201620'):
        pass
    • 對於函數的默認值謹慎使用可變類型。
    # 若是想要給value設置默認值是空列表
    
    # 不推薦
    # 由於在創建函數時, 就已經建立了一個空列表. 在調用函數時, 若不傳遞value參數, 則調用的函數執行時, value指向同一個地址。
    def func(data, value = []):
        pass
    
    # 推薦
    def func(data, value = None):
        if not None:
            value = []
    • 例子編碼

      # 方法一
      def func(data, value = []):
          value.append(data)
          return value
      
      v = func(1)
      v1 = func(1,[11,22,33])
      print(v)
      v2 = func(2)
      print(v,v1,v2)
      
      # 輸出結果
      [1]
      [1, 2] [11, 22, 33, 1] [1, 2]
      # 方法二
      def func(data, value = None):
          if not value:
              value = []
          value.append(data)
          return value
      
      v = func(1)
      v1 = func(1,[11,22,33])
      print(v)
      v2 = func(2)
      print(v,v1,v2)
      
      #輸出結果
      [1]
      [1] [11, 22, 33, 1] [2]
  • 特殊的形參code

    def func(*args, **kwargs):
        pass
    
    # 其中*args用來接受除字典之外的其餘類型的參數, **kwargs用來接受字典類型的參數

1.2 實參

調用函數時,傳入的參數。對象

def fun(name, age, num):
    pass
fun('aaron', 20, '201620')
  • 注意遞歸

    函數的參數傳遞的是內存地址(引用)。內存

1.3 返回值

誰調用了函數,函數的返回值就賦值給誰,當沒指定返回值時,默認返回None。ci

def fun(name, age, num):
    return name, age, num
  • 注意
    • 函數不被調用,函數內部的語句就不會被執行!!!
    • 每次調用函數時,都會爲這次調用開闢一塊內存,內存能夠保存本身之後想要用的值。

2. 匿名函數

  • 定義

    所謂的匿名函數就是沒有函數名的函數,而是用lambda關鍵字來進行定義。

lambda x, y: x + y
  • 上面的式子的功能等價於下面的函數。
def fun(x, y):
    return x + y

3. 遞歸函數

  • 本身調用本身的函數
def recursion():
    num = input('請輸入一個阿拉伯數字:')
    if num.isdecimal():
        print('輸入成功')
    else:
        print('\n輸入錯誤! 從新開始!\n')
        recursion() # 在此處調用了本身

recursion()

# 注意:Python默認的遞歸次數爲1000次。

4. 閉包

  • 定義

    爲函數建立一個區域(內部變量供本身使用),爲它之後執行提供數據。

name = 'oldboy'
def bar(name):
    def inner():
        print(name)
    return inner
v1 = bar('alex') # {name = alex, inner} # 閉包
v2 = bar('eric')
v1()
v2()
  • 例題

    • 例子1
    name = 'alex'
    def base():
        print(name)
    
    def func():
        name = 'eric'
        base()   
    func()
    
    # 輸出結果爲
    alex
    • 例子2
    info = []
    
    def func(i):
        def inner():
            print(i)
        return inner
    
    for item in range(10):
        info.append(func(item))
    
    info[0]()
    info[1]()
    info[4]()
    
    # 輸出結果爲
    0
    1
    4
    • 例子3
    name ='aaron'
    def fun():
        def inner():
            print(name)
        return inner() # 至關於 v = inner();return v  inner無返回值,因此v = None, 調用fun()的返回值就爲None
        # return inner # 若語句爲左邊所示,則最後的輸出結果爲inner函數所在的內存地址
    r = fun()
    print(r)
  • 注意

    # 不是閉包
    def bar(name):
        def inner():
            return 123
        return inner
    
    # 是閉包: 封裝值 + 內層函數須要使用
    def bar(name):
        def inner():
            print(name)
            return 123
        return inner

5. 內置函數

  • 經常使用內置函數
id:# 查看地址值
type:# 查看類型
repr:# 不轉義字符輸出字符串
chr:# 將ASCII編碼轉換爲字符
ord:# 將字符轉換爲ASCII編碼
eval:# 將字符串看成Python代碼執行(只能是一行字符串)
exec:# 將字符串看成Python代碼執行(能夠是多行字符串)
dir:# 獲取當前數據內置的方法屬性
len:# 求長度
range:# 生成一系列的數字
open:# 打開文件
input:# 輸入
print:# 輸出
help:# 幫助

'''
注意:關於上述提到的id是用來查看地址值的,這裏補充一下is和==的區別。
is:用來判斷兩個變量的地址是否相同。
==:用來判斷兩個變量的值是否相同。
'''
  • 例子

    a = 'print("i am eval")'
    
    b = '''
    i = 1
    if i == 1:
        print('True')
    else:
        print('False')
    '''
    eval(a)
    exec(a)
    exec(b)
    
    c = chr(65)
    print(c)
    
    d = ord('A')
    print(d)
    
    e = 'I am \n repr.'
    print(e)
    print(repr(e), type(repr(e)))
    
    f = [1, 2, 'a']
    g = [1, 2, 'a']
    print(f == g)
    print(f is g)
    print('f的地址:', id(f), '\ng的地址:', id(g))
    
    # 輸出結果
    i am eval
    i am eval
    True
    A
    65
    I am 
     repr.
    'I am \n repr.' <class 'str'>
    True
    False
    f的地址: 2215346431168 
    g的地址: 2215347343744
  • 高級內置函數

    • map, 循環可迭代對象中的每一個元素, 而後將每一個元素執行函數, 將每次的執行的結果保存到一個迭代器中, 並返回。
    # 格式:map(函數, 可迭代對象)
    
    v1 = [1, 2, 3, 4, 5]
    # 將v1中的每一個元素都加10
    result1 = map(lambda x: x + 10, v1)
    # 將v1中的每一個元素都乘10
    result2 = map(lambda x: x * 10, v1)
    
    print(result1)
    result3 = []
    for i in result1:
        result3.append(i)
    print(result3)
    
    print(result2)
      result4 = []
      for i in result2:
          result4.append(i)
      print(result4)
    
    # 輸出結果
      <map object at 0x0000021384B5E940>
      [11, 12, 13, 14, 15]
      <map object at 0x0000021384B89FD0>
      [10, 20, 30, 40, 50]
    • filter,循環可迭代對象中的每一個元素, 而後將每一個元素執行函數, 將每一個知足函數條件的元素保存到一個迭代器中, 並返回。
    # 格式:filter(函數, 可迭代對象)
    
      v1 = [11, 22, 'aa', 33, 'bb']
      # 求v1中類型爲int的元素
      result1 = filter(lambda x: type(x) == int, v1)
      # 求v1中類型爲str的元素
      result2 = filter(lambda x: type(x) == str, v1)
    
      print(result1)
      result3 = []
      for i in result1:
          result3.append(i)
      print(result3)
    
      print(result2)
      result4 = []
      for i in result2:
          result4.append(i)
      print(result4)
    
      # 輸出結果
      <filter object at 0x00000175EADDD048>
      [11, 22, 33]
      <filter object at 0x00000175EBE5CBA8>
      ['aa', 'bb']
    • 注意

      map和filter的返回值是一個迭代器,若直接輸出,則獲得的是一個地址值;對其進行for循環操做才能獲得其值;或者直接用list()將迭代器強制轉換成列表,可直接獲得其值。

    v1 = [11, 22, 'aa', 33, 'bb']
    result = filter(lambda x: type(x) == int, v1)
    print(list(result))
    
    # 輸出結果
    [11, 22, 33]

    上述所說的是在Python3的版本下的執行結果;如果在Python2的版本下,map和filter的返回值將是一個列表

    • reduce,可迭代對象中的元素循環執行函數,函數必須有兩個形參,每次傳入的兩個參數中有一個是上一次執行獲得的結果(只有第一次是傳入第二個參數中的兩個參數),將最終的結果保存到一個迭代器中,並返回。這是模塊functools中的一個函數,將其放在此處是由於其使用方式和map、filter比較類似。
    # 格式:reduce(函數, 可迭代對象)
    
      from functools import reduce
      v1 = [1, 10, 100, 1000]
      # 求v1中元素的和
      result1 = reduce(lambda x, y: x + y, v1)
      # 求v1中元素的乘積
      result2 = reduce(lambda x, y: x * y, v1)
      print(result1)
      print(result2)
    
      # 輸出結果
      1111
      1000000
相關文章
相關標籤/搜索