在本教程的開始部分,就已經引入了函數的概念:[《永遠強大的函數》](https://github.com/qiwsir/ITArticles/blob/master/BasicPython/106.md),之所以那時候就提到函數,是因為我覺得函數之重要,遠遠超過一般。這里,重回函數,一是復習,二是要在已經學習的基礎上,對函數有更深刻的理解。
## 函數的基本結構
Python中的函數基本結構:
~~~
def 函數名([參數列表]):
語句
~~~
幾點說明:
* 函數名的命名規則要符合python中的命名要求。一般用小寫字母和單下劃線、數字等組合
* def是函數的開始,這個簡寫來自英文單詞define,顯然,就是要定義一個什么東西
* 函數名后面是圓括號,括號里面,可以有參數列表,也可以沒有參數
* 千萬不要忘記了括號后面的冒號
* 語句,相對于def縮進,按照python習慣,縮進四個空格
看簡單例子,深入理解上面的要點:
~~~
>>> def name(): #定義一個無參數的函數,只是通過這個函數打印
... print "qiwsir" #縮進4個空格
...
>>> name() #調用函數,打印結果
qiwsir
>>> def add(x,y): #定義一個非常簡單的函數
... return x+y #縮進4個空格
...
>>> add(2,3) #通過函數,計算2+3
5
~~~
注意上面的add(x,y)函數,在這個函數中,沒有特別規定參數x,y的類型。其實,這句話本身就是錯的,還記得在前面已經多次提到,在python中,變量無類型,只有對象才有類型,這句話應該說成:x,y并沒有嚴格規定其所引用的對象類型。
為什么?列位不要忘記了,這里的所謂參數,跟前面說的變量,本質上是一回事。python中不需要提前聲明變量,有的語言就需要聲明。只有當用到該變量的時候,才建立變量與對象的對應關系,否則,關系不建立。而對象才有不同的類型。那么,在add(x,y)函數中,x,y在引用對象之前,是完全自由的,也就是它們可以引用任何對象,只要后面的運算許可,如果后面的運算不許可,則會報錯。
~~~
>>> add("qiw","sir") #這里,x="qiw",y="sir",讓函數計算x+y,也就是"qiw"+"sir"
'qiwsir'
>>> add("qiwsir",4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in add
TypeError: cannot concatenate 'str' and 'int' objects #仔細閱讀報錯信息,就明白錯誤之處了
~~~
從實驗結果中發現:x+y的意義完全取決于對象的類型。在python中,將這種依賴關系,稱之為**多態**。這是python和其它的靜態語言的重要區別。在python中,代碼不關心特定的數據類型。
對于python中的多態問題,以后還會遇到,這里僅僅以此例子顯示一番。請看官要留心注意的:**python中為對象編寫接口,而不是為數據類型。**
此外,也可以將函數通過賦值語句,與某個變量建立引用關系:
~~~
>>> result = add(3,4)
>>> result
7
~~~
在這里,其實解釋了函數的一個秘密。add(x,y)在被運行之前,計算機內是不存在的,直到代碼運行到這里的時候,在計算機中,就建立起來了一個對象,這就如同前面所學習過的字符串、列表等類型的對象一樣,運行add(x,y)之后,也建立了一個add(x,y)的對象,這個對象與變量result可以建立引用關系,并且add(x,y)將運算結果返回。于是,通過result就可以查看運算結果。
如果看官上面一段,感覺有點吃力或者暈乎,也不要緊,那就再讀一邊。是在搞不明白,就不要搞了。隨著學習的深入,它會被明白的。
## 調用函數
扯了不少函數怎么編寫,到底編寫函數有什么用?在程序中怎么調用呢?
為什么要寫函數?從理論上說,不用函數,也能夠編程,我們在前面已經寫了一個猜數字的程序,在那么就沒有寫函數,當然,用python的函數不算了。現在之所以使用函數,主要是:
1. 降低編程的難度,通常將一個復雜的大問題分解成一系列更簡單的小問題,然后將小問題繼續劃分成更小的問題,當問題細化為足夠簡單時,就可以分而治之。為了實現這種分而治之的設想,就要通過編寫函數,將各個小問題逐個擊破,再集合起來,解決大的問題。(看官請注意,分而治之的思想是編程的一個重要思想,所謂“分治”方法也。)
2. 代碼重(chong,二聲音)用。在編程的過程中,比較忌諱同樣一段代碼不斷的重復,所以,可以定義一個函數,在程序的多個位置使用,也可以用于多個程序。當然,后面我們還會講到“模塊”(此前也涉及到了,就是import導入的那個東西),還可以把函數放到一個模塊中供其他程序員使用。也可以使用其他程序員定義的函數(比如import ...,前面已經用到了,就是應用了別人——創造python的人——寫好的函數)。這就避免了重復勞動,提供了工作效率。
這樣看來,函數還是很必要的了。廢話少說,那就看函數怎么調用吧。以add(x,y)為例,前面已經演示了基本調用方式,此外,還可以這樣:
~~~
>>> def add(x,y): #為了能夠更明了顯示參數賦值特點,重寫此函數
... print "x=",x #分別打印參數賦值結果
... print "y=",y
... return x+y
...
>>> add(10,3) #x=10,y=3
x= 10
y= 3
13
>>> add(x=10,y=3) #同上
x= 10
y= 3
13
>>> add(y=10,x=3) #x=3,y=10
x= 3
y= 10
13
>>> add(3,10) #x=3,y=10
x= 3
y= 10
13
~~~
在定義函數的時候,參數可以想前面那樣,等待被賦值,也可以定義的時候就賦給一個默認值。例如:
~~~
>>> def times(x,y=2): #y的默認值為2
... print "x=",x
... print "y=",y
... return x*y
...
>>> times(3) #x=3,y=2
x= 3
y= 2
6
>>> times(x=3) #同上
x= 3
y= 2
6
>>> times(3,4) #x=3,y=4,y的值不再是2
x= 3
y= 4
12
>>> times("qiwsir") #再次體現了多態特點
x= qiwsir
y= 2
'qiwsirqiwsir'
~~~
給列位看官提一個思考題,請在閑暇之余用python完成:寫兩個數的加、減、乘、除的函數,然后用這些函數,完成簡單的計算。
## 注意事項
下面的若干條,是常見編寫代碼的注意事項:
1. 別忘了冒號。一定要記住符合語句首行末尾輸入“:”(if,while,for等的第一行)
2. 從第一行開始。要確定頂層(無嵌套)程序代碼從第一行開始。
3. 空白行在交互模式提示符下很重要。模塊文件中符合語句內的空白行常被忽視。但是,當你在交互模式提示符下輸入代碼時,空白行則是會結束語句。
4. 縮進要一致。避免在塊縮進中混合制表符和空格。
5. 使用簡潔的for循環,而不是while or range.相比,for循環更易寫,運行起來也更快
6. 要注意賦值語句中的可變對象。
7. 不要期待在原處修改的函數會返回結果,比如list.append()
8. 一定要之用括號調用函數
9. 不要在導入和重載中使用擴展名或路徑。
- 第零部分 獨上高樓,望盡天涯路
- 嘮叨一些關于Python的事情
- 為什么要開設本欄目
- 第一部分 積小流,至江海
- Python環境安裝
- 集成開發環境(IDE)
- 數的類型和四則運算
- 啰嗦的除法
- 開始真正編程
- 初識永遠強大的函數
- 玩轉字符串(1):基本概念、字符轉義、字符串連接、變量與字符串關系
- 玩轉字符串(2)
- 玩轉字符串(3)
- 眼花繚亂的運算符
- 從if開始語句的征程
- 一個免費的實驗室
- 有容乃大的list(1)
- 有容乃大的list(2)
- 有容乃大的list(3)
- 有容乃大的list(4)
- list和str比較
- 畫圈還不簡單嗎
- 再深點,更懂list
- 字典,你還記得嗎?
- 字典的操作方法
- 有點簡約的元組
- 一二三,集合了
- 集合的關系
- Python數據類型總結
- 深入變量和引用對象
- 賦值,簡單也不簡單
- 坑爹的字符編碼
- 做一個小游戲
- 不要紅頭文件(1): open, write, close
- 不要紅頭文件(2): os.stat, closed, mode, read, readlines, readline
- 第二部分 窮千里目,上一層樓
- 正規地說一句話
- print能干的事情
- 從格式化表達式到方法
- 復習if語句
- 用while來循環
- 難以想象的for
- 關于循環的小伎倆
- 讓人歡喜讓人憂的迭代
- 大話題小函數(1)
- 大話題小函數(2)
- python文檔
- 重回函數
- 變量和參數
- 總結參數的傳遞
- 傳說中的函數條規
- 關于類的基本認識
- 編寫類之一創建實例
- 編寫類之二方法
- 編寫類之三子類
- 編寫類之四再論繼承
- 命名空間
- 類的細節
- Import 模塊
- 模塊的加載
- 私有和專有
- 折騰一下目錄: os.path.<attribute>
- 第三部分 昨夜西風,亭臺誰登
- 網站的結構:網站組成、MySQL數據庫的安裝和配置、MySQL的運行
- 通過Python連接數據庫:安裝python-MySQLdb,連接MySQL
- 用Pyton操作數據庫(1):建立連接和游標,并insert and commit
- 用Python操作數據庫(2)
- 用Python操作數據庫(3)
- python開發框架:框架介紹、Tornado安裝
- Hello,第一個網頁分析:tornado網站的基本結構剖析:improt模塊、RequestHandler, HTTPServer, Application, IOLoop
- 實例分析get和post:get()通過URL得到數據和post()通過get_argument()獲取數據
- 問候世界:利用GAE建立tornado框架網站
- 使用表單和模板:tornado模板self.render和模板變量傳遞
- 模板中的語法:tornado模板中的for,if,set等語法
- 靜態文件以及一個項目框架
- 模板轉義
- 第四部分 暮然回首,燈火闌珊處
- requests庫
- 比較json/dictionary的庫
- defaultdict 模塊和 namedtuple 模塊
- 第五部分 Python備忘錄
- 基本的(字面量)值
- 運算符
- 常用的內建函數
- 擴展閱讀(來自網絡文章)
- 人生苦短,我用Python