python3-基礎5

#函數python

 1 什麼是函數?
 2 爲何要用函數? 3 函數的分類:內置函數與自定義函數 4 如何自定義函數 5  語法 6  定義有參數函數,及有參函數的應用場景 7  定義無參數函數,及無參函數的應用場景 8  定義空函數,及空函數的應用場景 9 調用函數 10  如何調用函數 11  函數的返回值 12 函數參數的應用:形參和實參,位置參數,關鍵字參數,默認參數,*args,**kwargs 13 高階函數(函數對象) 14 函數嵌套 15 做用域與名稱空間 16 裝飾器 17 迭代器與生成器及協程函數 18 三元運算,列表解析、生成器表達式 19 函數的遞歸調用 20 內置函數 21 面向過程編程與函數式編程

生活中要作某件事的時候,可能會用到各類工具,且能夠重複使用。git

遇到這種狀況,如何解決問題:編程

工具就具有某一種功能的物件,就是程序中的函數的概念app

事先準備工具的過程稱爲函數的定義函數式編程

遇到特定的場景拿來就用稱爲函數的調用函數

 

函數的分類工具

  內置函數: 爲了方便開發,針對一些簡單的功能,python解釋器已經爲咱們定義好了的函數即內置函數。spa

        對於內置函數,咱們能夠拿來就用而無需事先定義,如len(),sum(),max()設計

  自定義函數 :很明顯內置函數所能提供的功能是有限的,這就須要咱們本身根據需求,事先定製好咱們本身的函數來實現某種功能,code

        之後,在遇到應用場景時,調用自定義的函數便可。

 

 函數的定義語法:

     關鍵字  def  來定義

  def    函數名  (參數1,參數2,。。。):

     「註釋」

     函數體

     return 返回值   # 若此處爲print()     則函數的值不能賦值給變量 

  函數名通常是動詞,表示一個功能,要幹什麼

   註釋信息必定要有 

 return :函數內部能夠沒有return,返回None,等同於 return None

     若是return 後面跟一個值 , 將返回該值 , 這個值沒有類型限制, 字符串、數字、列表等均可以返回

        若是return 後面跟多個值 , 將返回一個元組,裏面包含多個值

             也能夠有多個return,可是隻能執行一次,函數就結束調用,而且會吧return後的值做爲函數執行的結果返回。

何時該有返回值?
    調用函數,通過一系列的操做,最後要拿到一個明確的結果,則必需要有返回值。
    一般有參函數須要有返回值,輸入參數,通過計算,獲得一個最終的結果。
何時不須要有返回值?
    調用函數,僅僅只是執行一系列的操做,最後不須要獲得什麼結果,則無需有返回值。
    一般無參函數不須要有返回值。

 

函數的使用,兩個階段

  一、先定義 :  def  func-name(空,或者參數1,參數2,。。。):

         func

         ruturn 值

  二、再調用 :  func-name()

 函數在定義階段,只檢測語法,不執行代碼。

 函數在調用階段,找已經定義的函數的名字,執行函數的內容

 

函數名和變量名: 

  本質同樣,都是名字,函數的定義與變量的定義相似,沒有事先定義變量,而直接引用變量,會報錯

  沒有事先定義函數,而直接引用函數,至關於在引用一個不存在的變量名。

  函數名加括號能夠傳參,變量名不行

 

定義函數的三種形式:

無參函數:應用場景僅僅只是執行一些操做,好比與用戶交互、打印,通常就是一些可執行的語句,普通操做等等

有參函數:須要根據外部傳進來的參數,才能執行響應的邏輯,好比統計長度、求最大值等等

空函數: 設計代碼結構,編程的一種思路

  def bar():

      pass

 

 1 #有參函數,注意返回值用return
 2 #求最大值
 3 def my_max(x,y):
 4     if x > y:
 5         # print(x)    #若爲print   則返回的值不能賦值給變量
 6         return x
 7     else:
 8         # print(y)
 9         return y
10 
11 res=my_max(1,2)
12 print(res)

函數調用的三種形式(如上例):

  調用函數的語句形式 :  my_max(1,2)

  調用函數做爲表達式 :  my_max(1,2)*10

  將函數做爲另外一個函數的參數   :   my_max(my_max(1,2) , 3)

 

函數參數:

  形參 : 形式上的參數,不佔內存空間,實際上就是變量名

  實參 : 實際存在的參數,佔內存空間,實際上就是變量值

在定義函數階段,函數括號內的參數是形參

在調用函數階段,函數括號內的參數是實參  

變量名和變量值是綁定關係,再調用階段,實參(變量值)纔會綁定到形參(變量名),調用結束後,解除綁定。

 

參數的分類:

  位置參數 :按照從左到右的順序,依次定義的參數

    位置形參:必選參數,必須被傳值,多一個不行,少一個也不行

    位置實參:按照位置給形參傳值,與形參按照位置一一對應

 

  關鍵字參數---關鍵字實參:無需按照位置爲形參傳值

          按照name = value 的形式定義的實參,指名道姓的給name傳值    fun(age = 18 , name= 'lalal')

          注意的問題:               

      1. 關鍵字實參必須在位置實參右面

      2. 對同一個形參不能重複傳值

  位置實參必須在關鍵字實參前面,關鍵字參數只能放在位置實參後面。

    形參 在什麼狀況下 必須被定義  , 每次都須要一個不一樣的值, 就要定義成位置參數。

         形參 默認參數是 , 值是固定的,每次調用均可以不傳值。

  默認參數須要注意的問題:

    問題一:默認參數要在位置參數以後,不然報錯

      def   foo(x , y=1)

        print(x,y)

    問題二:默認參數,只在定義階段賦值一次,並且,僅賦值一次。

      問題三: 默認參數的值,應該定義成不可變類型

  默認參數:形參在定義時就已經爲其賦值

        能夠傳值也能夠不傳值,常常須要變得參數定義成位置形參,變化較小的參數定義成默認參數(形參)
        注意的問題:
                1. 只在定義時賦值一次
                2. 默認參數的定義應該在位置形參右面
                3. 默認參數一般應該定義成不可變類型


 可變長參數: 指的是 實參的個數多了,不固定(實參有位置實參和關鍵字實參兩種)

 

 形參必需要兩種機制來分別處理

      按照位置定義的實參溢出的狀況:  *變量名    (一般   *args)     *就到表多出來的位置參數

      按照關鍵字定義的實參溢出的狀況: **變量名    (一般 **kwargs)

可變長指的是實參值的個數不固定
而實參有按位置和按關鍵字兩種形式定義,針對這兩種形式的可變長,形參對應有兩種解決方案來完整地存放它們,分別是*args,**kwargs

 1 #可變長位置實參
 2 def foo(x,y,*num):
 3     print(x)
 4     print(y)
 5     print(num)
 6 foo(2,4,6,8,9,3,5,)  
 7 
 8 #結果
 9 2
10 4
11 (6, 8, 9, 3, 5)    #多出來的參數,會組成一個元組,賦值給num
 1 #可變長關鍵字實參 **
 2 def foo(x,y,**num):
 3     print(x)
 4     print(y)
 5     print(num)
 6 foo(x=5,y=7,z=0,d=8,k=9,s=2,)    
 7 
 8 #結果
 9 5
10 7
11 {'z': 0, 'd': 8, 'k': 9, 's': 2}    #多餘的關鍵字實參,會組成一個字典,賦值給num

 

擴展用法

  若遇到實參裏面有*的參數,把參數打回原形,再傳參 

1 def foo(x,y):
2     print(x)
3     print(y)
4 #foo(2,4,*(6,8,9,3,5,))    #實參中有*號,表示的是多餘的位置實參,打回原形至關於  foo(2,4,6,8,9,3,5,),則最終會報錯
5 foo(2,*(6,))   #若實參的個數恰好和形參一一對應,則能夠正常賦值,不報錯
6 
7 #結果
8 2
9 6

 

 命名關鍵字參數:在*後面定義的形參稱爲命名關鍵字參數,必須是被以關鍵字實參的形式傳值

 1 #這倆東西 *args,**kwargs作什麼用???
 2 def register(name,age,sex='male'):
 3     print(name)
 4     print(age)
 5     print(sex)
 6 
 7 ##裝飾器概念(不改源代碼的狀況下,知足要求),一個函數調用另外一個函數
 8 def wrapper(*args,**kwargs): #萬用形參,不過切記,位置參數在關鍵字參數前面
 9     print(args)
10     print(kwargs)
11     register(*args,**kwargs)    #調用另外一個函數
12 #     register(*(1, 2, 3),**{'a': 1, 'b': 2})
13 #     register(1, 2, 3,a=1,b=2)
14 
15 
16 wrapper('lalala' , 28)    #實參是什麼就原生態的傳給register什麼
 

 練習:

 

 

函數對象:  函數是第一類對象,能夠被當作數據傳遞

被賦值

能夠當作參數傳入

能夠當作函數的返回值

能夠當作容器類型的元素

 1 '''
 2 階段性練習
 3 一、寫函數,,用戶傳入修改的文件名,與要修改的內容,執行函數,完成批了修改操做
 4 二、寫函數,計算傳入字符串中【數字】、【字母】、【空格] 以及 【其餘】的個數
 5 
 6 三、寫函數,判斷用戶傳入的對象(字符串、列表、元組)長度是否大於5。
 7 
 8 四、寫函數,檢查傳入列表的長度,若是大於2,那麼僅保留前兩個長度的內容,並將新內容返回給調用者。
 9 
10 五、寫函數,檢查獲取傳入列表或元組對象的全部奇數位索引對應的元素,並將其做爲新列表返回給調用者。
11 
12 六、寫函數,檢查字典的每個value的長度,若是大於2,那麼僅保留前兩個長度的內容,並將新內容返回給調用者。
13 dic = {"k1": "v1v1", "k2": [11,22,33,44]}
14 PS:字典中的value只能是字符串或列表
15 '''
16 
17 #======================>>
18 
19 
20 #題目一
21 def modify_file(filename,old,new):
22     import os
23     with open(filename,'r',encoding='utf-8') as read_f,\
24         open('.bak.swap','w',encoding='utf-8') as write_f:
25         for line in read_f:
26             if old in line:
27                 line=line.replace(old,new)
28             write_f.write(line)
29     os.remove(filename)
30     os.rename('.bak.swap',filename)
31 
32 modify_file('/Users/jieli/PycharmProjects/爬蟲/a.txt','alex','SB')
33 
34 #題目二
35 def check_str(msg):
36     res={
37         'num':0,
38         'string':0,
39         'space':0,
40         'other':0,
41     }
42     for s in msg:
43         if s.isdigit():
44             res['num']+=1
45         elif s.isalpha():
46             res['string']+=1
47         elif s.isspace():
48             res['space']+=1
49         else:
50             res['other']+=1
51     return res
52 
53 res=check_str('hello name:aSB passowrd:alex3714')
54 print(res)
55 
56 
57 #題目三:略
58 
59 #題目四
60 def func1(seq):
61     if len(seq) > 2:
62         seq=seq[0:2]
63     return seq
64 print(func1([1,2,3,4]))
65 
66 
67 #題目五
68 def func2(seq):
69     return seq[::2]
70 print(func2([1,2,3,4,5,6,7]))
71 
72 
73 #題目六
74 def func3(dic):
75     d={}
76     for k,v in dic.items():
77         if len(v) > 2:
78             d[k]=v[0:2]
79     return d
80 print(func3({'k1':'abcdef','k2':[1,2,3,4],'k3':('a','b','c')}))
相關文章
相關標籤/搜索