天天看點

Python子產品化程式設計-函數#學習猿地

### 子產品化程式設計

> 子產品化程式設計指把程式進行封裝(函數封裝,面向對象,檔案。。。)

#### 什麼是函數?

> function -> 函數,功能

>

> 函數就是一個具有特定功能的代碼塊

#### 函數的作用?

> 函數就是把代碼進行封裝,以提高代碼的重用性,提高開發效率,并且降低了後期的維護成本

#### 函數的定義和使用

```python

# 定義函數【基本結構】

def 函數名([參數清單]):

  目前函數的具體功能的代碼

  目前函數的具體功能的代碼

  。。。。

# 函數封裝完并不會執行,隻是把函數定義了而已

# 如果想使用定義的函數,那麼就需要用文法來進行函數的調用

# 函數的調用

函數名()

```

#### 函數的特征及注意事項

1. 函數定義後,不調用不執行

2. 不能在函數定義前調用函數

3. 函數的調用不受次數影響

4. 函數的命名要遵守命名規範

  + 字母數字下劃線,不能以數字開頭

  + 嚴格區分大小寫,不能使用關鍵字

  + 命名最好有意義,且不要使用中文

5. 函數名不要沖突,沖突後會被覆寫

### 關于函數的參數

> 函數在定義時,可以在參數清單的位置定義形參

>

> 如果函數有形參,那麼在函數調用時也需要給定參數

>

> 實參将值傳遞給形參的過程,本質上就是變量指派操作

#### (1)函數參數概念及分類

  函數參數:調用時需要傳遞的資料.

  函數參數大類分為形參和實參:

  . 形參意思: 函數定義時的參數

  . 實參意思: 函數調用時的參數

  形實關系:函數調用時,形參和實參個數需要一一對應

  形參種類: 普通參數,預設參數,普通收集參數,命名關鍵字參數,關鍵字收集參數

  實參種類: 普通實參,關鍵字實參

#### (2)普通參數

(位置參數)普通的參數,接收實參傳遞的值

#### (3)預設參數:

> 位于普通參數後面,具有預設值的參數

>

> 文法:(x,y=2)  y就是預設參數

 #### (4)收集參數:

> 專門收集在函數調用時傳遞的多餘的實參

```

1.普通收集參數:專門用于收集多餘的普通參數,形成一個新的元組

文法:參數前面加* 例:*args

2.關鍵字收集參數:用于專門收集多餘關鍵字實參,形成一個新的字典

  文法:參數前面加** 例:**kwargs

```

#### (5)命名關鍵字參數

> 定義時放在*号後面的參數,調用時強制必須傳入指定參數名才能調用

```

文法:(a,*,x) x是命名關鍵字參數

如果函數參數中已經有了收集參數,那麼收集參數後面的參數即為命名關鍵字參數

  文法:(*args,x,y)

```

#### (6)形參聲明的位置順序:

> 普通參數 -> 預設參數 -> 收集參數 -> 命名關鍵字參數 -> 關鍵字收集參數

```

def func(a,b,c=1,*args,d,**kw)

a,b為普通參數,c是預設參數,args是收集參數,d是命名關鍵字參數,kw是關鍵字收集參數

極少出現五種參數同時出現的情況

def func(a,b=2,*,c,d,**kw)

a為普通參數,b是預設參數,c,d是命名關鍵字參數 ,kw是關鍵字收集參數

```

 #### 所有參數的擺放問題

- 實參:普通實參在前,關鍵字參數在後

- 形參:

 - 關鍵字收集參數一定在最後出現

 - 收集參數推薦在普通參數之後使用

- 推薦順序:普通形參,收集參數,關鍵字收集參數

### 函數傳回值

> 一個函數除來可以完成一定功能之外,還可以按需要傳回一些内容

>

> 函數中使用 return 關鍵字來指定傳回資料,可以傳回任意類型的資料

>

> 函數的傳回值,會把資料傳回到調用處,可以使用變量接收,或其它處理

```

函數可以分為兩類

  1。執行過程函數: 函數體内完成一定的功能既可,沒有傳回值

  2。具有傳回值的函數: 函數體内完成一定的功能,并且傳回一個結果到函數調用處

```

#### return傳回值的特征

+ 函數中可以使用 return 進行資料的傳回

+ 可以使用return 傳回 任意内容或資料

+ return 會把傳回值,傳回到函數調用出

+ return 意味着函數的結束,return之後的代碼不在執行

+ 如果在函數中沒有使用return 或者 return後面沒有任何内容,那麼預設傳回 None

```python

# 假設有這樣一個需求,定義一個函數,完成兩個數的計算,并把結果輸出

# def jia(n1,n2):

#   res = n1+n2

#   print(res)

# jia(2,5)

# 需求改變,定義一個函數,完成兩個數的計算,并把結果傳回

def jia(n1,n2):

  res = n1+n2

  return res

r = jia(2,4)

print(r)

```

### 變量作用域

> 作用域就是目前起作用,可用的範圍區域

>

> 變量的有效範圍

全局變量:在函數内外都可以使用的變量

局部變量:在函數内部可以使用的變量

```

局部變量

  函數内定義的變量,局部變量,在函數外不能使用

全局變量

  在函數内部使用 global 直接定義的變量,就是全局變量,函數内外都可以使用

  在函數外定義的變量,在函數内使用 global 關鍵字進行聲明,那麼也是全局變量

globals() 擷取全局資料

locals() 擷取目前作用域的資料

  在函數外定義的變量,函數可以通路,但是不能更改

資料類型的分類:

  可變資料類型:在函數外定義的變量,在函數可以使用,

    清單和字典

  不可變資料類型:在函數外定義的變量,在函數内隻能通路,不能使用其它操作

```

#### 不光變量有作用域,函數一樣也有相同的作用域

```python

def outer():

  print('this is outer function...')

  # 在函數内定義的函數,稱為 局部函數,函數外無法使用

  def inner():

    print('this is inner function...')

  inner()

outer()

# inner()

```

### nonlocal

> 在内函數中如何使用上一層函數中的局部變量?

> 在内函數中如果想使用外層函數的變量,那麼需要使用 nonlocal 關鍵字 引用

> 可以引用上一層函數中定義的局部變量,但依然不能提升為全局變量

```python

# 定義一個外層函數

def outer():

  # 外函數的局部變量

  num = 10

  # 内函數,局部函數,在函數的内部定義的函數

  def inner():

    # nonlocal 關鍵字在局部函數中使用,

    nonlocal num # 可以引用上一層函數中定義的局部變量,但依然不能提升為全局變量

    num += 1

    print(num)

  inner()

outer()

# print(num)

```

#### 關于函數的文檔

```python

def outer():

  '''

  這裡是讓你些目前函數的文檔說明的。

  需要說明目前函數的作用,

  如果目前函數還有行參,那麼也需要對行參進行一一說明

  name: 這個是一個name參數,有什麼作用。。。

  age : 這個表示目前的一個年齡

  :return: 此處說明目前函數的傳回值。。。

  '''

print(globals())

print(__name__) # 擷取目前腳本的檔案名,

print(__doc__) # 擷取目前腳本的說明文檔

# print(outer.__doc__) # 擷取目前函數的說明文檔

'''

魔術變量

__name__ ==> 目前腳本如果作為主程式,那麼值是 __main__,如果是當做一個子產品,在另外一個腳本中引用去使用,那麼值就是目前檔案的名字

__doc__  ==> 目前腳本的文檔說明 在目前腳本當中的第一個 三引号注釋就是目前腳本的說明文檔

{

  '__name__': '__main__', 

  '__doc__': '\n在内函數中如果想使用外層函數的變', 

  '__package__': None,

   '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x110444350>, 

   '__spec__': None, 

   '__annotations__': {}, 

   '__builtins__': <module 'builtins' (built-in)>, 

   '__file__': '/Users/yc/Desktop/code/8.nonlocal關鍵字.py', 

   '__cached__': None, 'outer': <function outer at 0x1104938c0>

}

'''

```