Python學習之函數

理解函數

高中數學中,學習的函數 有一次函數,二次函數,高次函數,正餘弦函數,正餘切函數、指數函數、冪函數等等,都是函數。從這一節開始,學習程序中的函數。

f(x) = ax + b
其中a、 b是常數,x是變量,f(x)隨x的變化而變化。那麼x就叫做函數的自變量,而f(x)叫做函數的因變量。
假如x = 2,那麼上面的函數式可以寫爲f(x) = a * 2 + b
這樣就不難理解程序中的函數了。
由於函數本身是一個表達式,這個表達式會根據自變量x的變化而得到不同的結果。所以,程序中,編寫的函數也是爲了根據參數方便被重複調用。
可以把x當作程序中的參數來理解。
和數學中函數不同的是,程序中的函數的參數並不是一個數,它可以是任何對象。

對於變量的理解

在程序中,變量不僅僅指的是一個具體的數字,也可以是任何對象。
再來拿一個列子,比如f(x) = 2 * x + 3,
那麼在這個一次函數中,如果x=2 那麼,f(x)= 2 * 2 + 3
結果爲7,我們便稱這是一個映射。
所以X可以是任何對象,只是我們在數學中習慣了將它作爲一個數字。
可以這樣理解,X就是一個佔位符,因爲我們不知道函數具體想要實現什麼,那麼這個位置暫且先用x來代替,讓其佔着這個位置,等待交互模式下的輸入。
所以,程序中的變量說過來要比我們中學時期學過的函數要複雜的多。
關於變量的命名,Python中一般使用小寫字母來作爲變量的開頭,也可以是下劃線,以表示區別。

建立一個簡單的函數

>>> x = 3
>>> y = 2 * x + 3
>>> y
9
>>> 

上面這個函數和中學學習的數學沒有任何區別,當然,在這就也沒有什麼實際的意義了,只是引出來作爲理解函數中的變量。

思考,如果我們這次讓x = 4 那麼y的值將會是多少?

>>> x = 3
>>> y = 2 * x + 3
>>> y
9
>>> x = 4
>>> y
9
>>> 

發現,y的結果依然沒有變,爲什麼呢?
原因是這樣的,我們在前面提到過變量,在Python中,變量無類型,對象有類型,我們只是將3 這個對象貼上了變量x的標籤。經過第一次計算,y引用的依然是x = 3這個變量計算後的標籤8,所以,我們只有再進行一個計算,這個結果就會跟着變化了。

>>> x = 3
>>> y = 2 * x + 3
>>> y
9
>>> x = 4
>>> y
9
>>> y = 2 * x + 3
>>> y
11
>>> 

有沒有發現,上面的函數在引用變量的時候,都是對變量進行先定義,然後再使用的,如果不預先定義,直接使用函數進行引用會發生什麼錯誤呢?
來看看:

>>> y = 2 * a + 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> 

上面的變量a是沒有預先定義的,所以,當直接用函數引用變量的時候出錯了。而且錯誤很明確,a 沒有被定義。
所以,無論是python還是java還是類C,對變量都是堅持先聲明,後使用的規則。記住這是規則。
在java中是這樣。

public class test{
    public static void main(String args[]){
        int c = a + 2;
        System.out.println(c);
    }
}
#然後再cmd命令窗口執行
D:\ProjectFiles\JavaFiles>javac test.java
test.java:3: 錯誤: 找不到符號
                int c = a + 2;
                        ^
  符號:   變量 a
  位置: 類 test
1 個錯誤

提示說找不到符號a ,那麼我們看代碼發現,並沒有定義變量a,然後我們定義一個變量a再進行運行程序

public class test{
    public static void main(String args[]){
        int a = 3;
        int c = a + 2;
        System.out.println(c);
    }
}
#然後再cmd命令窗口執行:
D:\ProjectFiles\JavaFiles>javac test.java     #編譯通過

D:\ProjectFiles\JavaFiles>java test
5

D:\ProjectFiles\JavaFiles>

java中的具體編譯結果,我在這裏就不解釋了。
C語言中是這樣的。
如果變量a未被定義:

#include <stdio.h>
void main(int){
    int c = a + 3;
    printf("%d", c);
}
錯誤  1   error C2065: “a”: 未聲明的標識符   d:\projectfiles\cfiles\consoleapplication1\consoleapplication1\源.cpp    3   1   ConsoleApplication1
    2   IntelliSense:  未定義標識符 "a"   d:\ProjectFiles\CFiles\ConsoleApplication1\ConsoleApplication1\源.cpp    3   10  ConsoleApplication1

如果a 被定義:

#include <stdio.h>
void main(int){
    int a = 3;
    int c = a + 3;
    printf("%d", c);
}

將會在cmd窗口顯示一個結果6,
所以,再三聲明,無論是哪種編程語言,變量必須是先聲明,後使用

建立實用的函數

上面寫的簡單函數只是爲了引進來讓理解函數和變量的關係。並沒有什麼實際的意義。所以,這次爲了讓函數“規範化”,寫一個.py的文件。
需求,定義一個函數,要求這個函數有兩個參數a,b,然後通過給函數傳遞參數,執行後並將結果輸出到屏幕上。

[root@python Script]# cat ftest.py 
#!/usr/bin/env python
#coding:utf-8
def add(a,b):
    c = a + b
    print c

if __name__ == "__main__":
    add(3,8)
[root@python Script]# python ftest.py 
11
[root@python Script]# 

說明:
def add(a,b):這是聲明一個名爲add並且參數爲a,b的函數。def也就是define定義的意思。
c = a + b :函數裏面的表達式塊,將a + b的結果賦值給c。
print c,將變量c 的結果輸出到屏幕上。
if name == “main“:這個暫時不用理解它,就當作程序的入口就行,記下來就行。
add(3,8):這個是調用前面定義的函數add並且傳入兩個實參3、8。
很好理解吧。

注意Python中函數的命名規則
· 函數名以數字、字母和下劃線組成
· def是Python中聲明函數的關鍵詞,也是define的簡寫。
· 函數名後面以一對圓括號結束,括號裏面可以有參數列表,也可以無參數列表,有參數列表的時候,參數列表數量並沒有限制
· 函數體當中的語句塊也是以四個空格爲縮進量。
練習:
減法函數:

>>> def sub(a,b):
...     c = a - b
...     print c
... 
>>> sub(4,1)
3
>>> 

乘法函數:

>>> def multiplication(a,b):
...     c = a * b
...     print c
... 
>>> multiplication(4,5)
20
>>> 

除法函數:

>>> def division(a,b):
...     c = b / a
...     print c
... 
>>> division(3,9)
3
>>> 

取餘函數:

>>> def remainer(a,b):
...     c = a % b
...     return c
... 
>>> remainer(10,3)
1
>>> 

說明:以上引入的參數都是沒有類型的,也一直提到變量無類型,只有對象纔是有類型的。所以在定義函數的時候,函數裏面的參數是不確定的,因爲它可以引用任何對象類型。只要函數體裏面的運算成立,變可以引用任何參數。如果函數體裏面的運算不成立,則會報錯。
示例

>>> def test(a,b):
...     return a + b
... 
>>> test("Python ","Java")
'Python Java'
>>> test("Python ",12345)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test
TypeError: cannot concatenate 'str' and 'int' objects

第一次調用的時候,因爲兩個參數都是字符串,所以連接沒有問題,但是第二個調用函數的時候,一個是字符串,一個是整型數值,所以返回的運算語句是不成立的,所以報錯。不過可以在實參的傳遞中進行類型轉換。

>>> test("Python ",str(12345))
'Python 12345'
>>> 

從實驗的結果中發現,返回的a + b完全取決於傳入參數的對象類型,而這種依賴關係被稱作多態,因爲Python也是一種面向對象的編程語言,所以,在這裏引出面向對象的三大特性,繼承、封裝、多態。
注意,Python中,爲對象編寫接口,而不是爲數據類型編寫接口

命名

Python中,命名的一般要求:
文件: 全小寫,也可以使用下劃線
函數名: 小寫,和下劃線使用,提高程序的可讀性,也可以採取駝峯命名。如:myEclipse
函數的參數: 如果一個函數的參數名稱和保留的關鍵字衝突,可以使用一個後綴的下劃線來區分
變量: 字母數字下劃線。

函數的調用

調用函數的好處:

降低編程的難度 通常將一個複雜的問題分解爲多個小的問題而解決,以減少編程的複雜程度。
代碼重用 通常也會叫做開耦合,避免重複調用一段代碼
示例函數的調用:

>>> def add(a,b):
...     print "a = ", a
...     print "b = ", b
...     c = a + b
...     print "c = ", c
... 
>>> add(1,2)
a =  1
b =  2
c =  3
>>> add(4,5)
a =  4
b =  5
c =  9
>>> 

注意,這樣寫一定要注意傳遞參數的次序,如果參數太多,次序記起來很麻煩,可以直接將參數的賦值寫到調用函數的模塊兒裏面,像下面這樣:

>>> add (a = 10,b = 4)
a =  10
b =  4
c =  14
>>> add(b = 3,a = 6)
a =  6
b =  3
c =  9
>>> 

也可以直接在定義函數的時候直接在參數列表中賦值,像下面這樣:

>>> def add(a,b = 2):
...     print "a = ",a
...     print "b = ",b
...     c = a + b
...     print "c = ",c
... 
>>> add(3)
a =  3
b =  2
c =  5
>>> add(a = 4,b = 6)                #也可以重新賦值。
a =  4
b =  6
c =  10
>>> 

返回值

Python中的返回值有兩種:
返回一個值
返回多個值
具體看一下文檔:
return_stmt ::= “return” [expression_list]

return may only occur syntactically nested in a function
definition, not within a nested class definition.

If an expression list is present, it is evaluated, else None is
substituted.

return leaves the current function call with the expression list
(or None) as return value.

When return passes control out of a try statement with a
:
說明:”return”只能在語法上嵌套在定義的函數中,而不是被嵌套在定義的類中。
如果一個表達式列表是存在的,那麼它將會被求值計算,否則將使用“None”替代
”return”離開當前函數調用的表達式並返回值。

上面說明中,類的定義在以後將會學習,這裏只看第三個。
示例:

>>> def add(a,b):
...     c = a + b
...     return c
... 
>>> add(1,2)
3
>>> def sub(a,b):
...     c = a * b
...     return c , a, b
... 
>>> sub(3,9)
(27, 3, 9)
>>> 

第一次接觸函數就暫時學習到這裏

完成於2017年05月17號
晚上20:30

發佈了47 篇原創文章 · 獲贊 16 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章