測開之函式進階· 第2篇《純函式》
阿新 • • 發佈:2020-12-22
### 堅持原創輸出,點選藍字關注我吧
![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201222145159.png)
作者:清菡
部落格:oschina、雲+社群、知乎等各大平臺都有。
> 由於微信公眾號推送改為了資訊流的形式,防止走丟,請給加個星標 ⭐,你就可以第一時間接收到本公眾號的推送!
# 目錄
- 一、純函式的概念
- 1.純函式
- 2.非純函式
- 3.純函式:相同的輸入保證相同的輸出
- 4.純函式和非純函式對比
- 二、純函式的 3 個原則
- 三、函式的副作用
- 四、Python 中的內建函式
重點需要記住純函式的概念和函式的副作用,面試會問,哈哈。
## 一、純函式的概念
一個函式的返回結果只依賴於它的引數,並且在執行過程裡面沒有副作用,我們就把這個函式叫做純函式。
純函式不是特定的語法,不是特定的功能,它只是一個概念。就是一個函式使用的時候的一種規則。
### 1.純函式
雖然這是個遞迴函式,它也是純函式的一種:
```python
def fun(n):
if n == -1:# 遞迴臨界點:當達到遞迴臨界點的時候,就不再呼叫自身函式的條件
return 1
else:
return n * fun(n-1) # 4 *3*2*1
fun(4)
```
### 2.非純函式
函式裡面進行一系列計算,它返回的結果是根據傳入的資料相關。不再依賴於任何的其它資料,比如定義個`a = 100`,那麼在:
```PYTHON
if n == 0:# 遞迴臨界點:當達到遞迴臨界點的時候,就不再呼叫自身函式的條件
return 1
else:
return n * fun(n-1) # 4 *3*2*1
```
這段程式碼,也就是純函式裡面用到了外面的變數:
```PYTHON
a = 100
def fun(n):
print(a)
if n == 0:# 遞迴臨界點:當達到遞迴臨界點的時候,就不再呼叫自身函式的條件
return 1
else:
return n * fun(n-1) # 4 *3*2*1
fun(4)
```
那這種函式就不再叫做純函數了。`print(a)`因為它對外部變數有引用。
### 3.純函式:相同的輸入保證相同的輸出
純函式不會引用外部的變數,它呼叫的結果只對你傳入進去的引數`fun(4)`有關。
例如:
定義`a=100`,`return a`返回一個 a,傳入引數`i`,`def func(i):`。
`這個時候呼叫這個函式,傳進去的引數跟它的返回值有關嗎?`
這個函式和它的返回值沒有關係。傳進去的`func(10)`,不管傳什麼,不會影響返回值`return a`。
```PYTHON
a = 100
def func(i):
print('99999')
print(i)
return a
func(10)
```
純函式是傳進去的引數是什麼,返回的結果只跟你的引數有關。
**純函式:不管在什麼時候呼叫(不管在哪裡呼叫),傳入的引數相同,返回的結果就一定是一樣的。**
例如:
這個函式,呼叫的時候傳個 10 進去,它返回的時候應該是多少呢?
它返回的結果是 110。
```PYTHON
a = 100
def func(i):
i = i + a
return i
res = func(10)
print(res)
```
![](https://gitee.com/qinghanstudy/qinghan/raw/master/img/20201222124321.png)
在下面對 a 進行修改,對 a 再賦個值:
`a = a+1111`
那麼這個時候,a 的值肯定發生變化了。這個時候在這裡再呼叫函式,再傳入 10,`func(10)`。
```PYTHON
a = 100
def func(i):
i = i + a
return i
res = func(10)
print(res)
a = a+1111
res2 = func(10)
print(res2)
```
同樣呼叫的是同一個函式,傳入的引數都是相同的`func(10)`,但是拿到的返回值卻不是相同的。
像這種函式,它會受外部環境變數的影響,那麼這種函式不能稱為純函式。
### 4.純函式和非純函式對比
```PYTHON
# 函式func1返回的結果為兩個引數相加的結果
def func1(a,b):
return a + b
var1=100
#函式func2返回的結果為引數a和外部變數var1相加的結果
def func2(a):
return var1+a
#在上面兩個案例中func1返回的結果只受傳入的引數的影響,而func2不僅
# 受傳入引數的影響還會受外部變數var1的影響,像func1這樣的返回值只跟
#傳入引數有關的函式,我們把它叫做純函式。
```
## 二、純函式的 3 個原則
原則一:變數都只在函式作用域內獲取,作為的函式的引數傳入。
原則二:不會產生副作用,不會改變被傳入的資料或者其它資料(全域性變數)。
原則三:相同的輸入保證相同的輸出。
解釋原則一:
純函式的變數只在函式的作用域內獲得,**也就是說純函式裡面要麼使用的是函式內部定義的,要麼使用的是傳進來的引數,不會再使用其它任何的變量了。**
解釋原則二:
純函式是不會產生副作用的。
解釋原則三:
任何時候呼叫,只要你傳入的引數是相同的,它給你返回的結果都是一樣的。
## 三、函式的副作用
函式的副作用就是當函式被呼叫的時候,既完成了(函式既定的計算任務)函式相關的功能,在完成函式相關功能的時候,你這個函式訪問了外部變數,尤其是對外部的資料進行了寫操作。
比如在函式內部用到了外面的列表,在這裡面還往列表裡面加了個元素。這個時候修改了全域性變數,造成外部環境發生了改變。這種就叫做函式的副作用。
## 四、Python 中的內建函式
**內建函式:** https://docs.python.org/zh-cn/3.7/library/functions.html
Python 中的內建函式包含的不僅僅是內建函式還有很多的內建型別。
雖然內建型別是個類,不是函式。Python 官方也把內建型別歸納在內建函式裡面,把它稱為內建函式。
`str()`底層是個類,但是 Python 官方是把它歸納在內建函式裡面的。
不管什麼時候呼叫內建函式,內建函式返回的結果只跟傳入的引數相關,任何時候傳進去的引數是一樣的,那麼內建函式返回的結果都是一樣的。
內建函式是沒有副作用的,全部是屬於純函式的一種,都是屬於純函式。
`str()`不是個函式,其實是個類。雖然算個內建函式,但是不能稱為純函式。
----------------
公眾號 **清菡軟體測試** 首發,更多原創文章:清菡軟體測試 111+原創文章,歡迎關注、交流,禁止第三方擅自