我們可以創建一個用來生成指定邊界的斐波那契數列的函數:
~~~
>>> def fib(n): # write Fibonacci series up to n
... """Print a Fibonacci series up to n."""
... a, b = 0, 1
... while a n:
... print(a, end=' ')
... a, b = b, a+b
... print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
~~~
關鍵字?def?引入了一個函數?_定義_。在其后必須跟有函數名和包括形式參數的圓括號。函數體語句從下一行開始,必須是縮進的。
函數體的第一行語句可以是可選的字符串文本,這個字符串是函數的文檔字符串,或者稱為_docstring_。(更多關于 docstrings 的信息請參考?[_文檔字符串_](http://www.pythondoc.com/pythontutorial3/controlflow.html#tut-docstrings)) 有些工具通過 docstrings 自動生成在線的或可打印的文檔,或者讓用戶通過代碼交互瀏覽;在你的代碼中包含 docstrings 是一個好的實踐,讓它成為習慣吧。
函數?_調用_?會為函數局部變量生成一個新的符號表。確切的說,所有函數中的變量賦值都是將值存儲在局部符號表。變量引用首先在局部符號表中查找,然后是包含函數的局部符號表,然后是全局符號表,最后是內置名字表。因此,全局變量不能在函數中直接賦值(除非用?global?語句命名),盡管他們可以被引用。
函數引用的實際參數在函數調用時引入局部符號表,因此,實參總是?_傳值調用_?(這里的?_值_?總是一個對象 引用 ,而不是該對象的值)。[[1]](http://www.pythondoc.com/pythontutorial3/controlflow.html#id10)?一個函數被另一個函數調用時,一個新的局部符號表在調用過程中被創建。
一個函數定義會在當前符號表內引入函數名。函數名指代的值(即函數體)有一個被 Python 解釋器認定為?_用戶自定義函數_?的類型。 這個值可以賦予其他的名字(即變量名),然后它也可以被當做函數使用。這可以作為通用的重命名機制:
~~~
>>> fib
>>> f = fib
>>> f(100)
0 1 1 2 3 5 8 13 21 34 55 89
~~~
如果你使用過其他語言,你可能會反對說:fib?不是一個函數,而是一個方法,因為它并不返回任何值。事實上,沒有?return?語句的函數確實會返回一個值,雖然是一個相當令人厭煩的值(指 None )。這個值被稱為?None?(這是一個內建名稱)。如果?None?值是唯一被書寫的值,那么在寫的時候通常會被解釋器忽略(即不輸出任何內容)。如果你確實想看到這個值的輸出內容,請使用print()?函數:
~~~
>>> fib(0)
>>> print(fib(0))
None
~~~
定義一個返回斐波那契數列數字列表的函數,而不是打印它,是很簡單的:
~~~
>>> def fib2(n): # return Fibonacci series up to n
... """Return a list containing the Fibonacci series up to n."""
... result = []
... a, b = 0, 1
... while a n:
... result.append(a) # see below
... a, b = b, a+b
... return result
...
>>> f100 = fib2(100) # call it
>>> f100 # write the result
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
~~~
和以前一樣,這個例子演示了一些新的 Python 功能:
* return?語句從函數中返回一個值,不帶表達式的?return?返回?None。過程結束后也會返回None。
* 語句?result.append(b)?稱為鏈表對象?result?的一個?_方法_。方法是一個“屬于”某個對象的函數,它被命名為?obj.methodename,這里的?obj?是某個對象(可能是一個表達式),?methodename?是某個在該對象類型定義中的方法的命名。不同的類型定義不同的方法。不同類型可能有同樣名字的方法,但不會混淆。(當你定義自己的對象類型和方法時,可能會出現這種情況,_class_?的定義方法詳見?[_類_](http://www.pythondoc.com/pythontutorial3/classes.html#tut-classes)?)。示例中演示的?append()?方法由鏈表對象定義,它向鏈表中加入一個新元素。在示例中它等同于?result?=?result?+?[b],不過效率更高。
- Python 入門指南
- 1. 開胃菜
- 2. 使用 Python 解釋器
- 2.1. 調用 Python 解釋器
- 2.2. 解釋器及其環境
- 3. Python 簡介
- 3.1. 將 Python 當做計算器
- 3.2. 編程的第一步
- 4. 深入 Python 流程控制
- 4.1. if 語句
- 4.2. for 語句
- 4.3. range() 函數
- 4.4. break 和 continue 語句, 以及循環中的 else 子句
- 4.5. pass 語句
- 4.6. 定義函數
- 4.7. 深入 Python 函數定義
- 4.8. 插曲:編碼風格
- 5. 數據結構
- 5.1. 關于列表更多的內容
- 5.2. del 語句
- 5.3. 元組和序列
- 5.4. 集合
- 5.5. 字典
- 5.6. 循環技巧
- 5.7. 深入條件控制
- 5.8. 比較序列和其它類型
- 6. 模塊
- 6.1. 深入模塊
- 6.2. 標準模塊
- 6.3. dir() 函數
- 6.4. 包
- 7. 輸入和輸出
- 7.1. 格式化輸出
- 7.2. 文件讀寫
- 8. 錯誤和異常
- 8.1. 語法錯誤
- 8.2. 異常
- 8.3. 異常處理
- 8.4. 拋出異常
- 8.5. 用戶自定義異常
- 8.6. 定義清理行為
- 8.7. 預定義清理行為
- 9. 類
- 9.1. 術語相關
- 9.2. Python 作用域和命名空間
- 9.3. 初識類
- 9.4. 一些說明
- 9.5. 繼承
- 9.6. 私有變量
- 9.7. 補充
- 9.8. 異常也是類
- 9.9. 迭代器
- 9.10. 生成器
- 9.11. 生成器表達式
- 10. Python 標準庫概覽
- 10.1. 操作系統接口
- 10.2. 文件通配符
- 10.3. 命令行參數
- 10.4. 錯誤輸出重定向和程序終止
- 10.5. 字符串正則匹配
- 10.6. 數學
- 10.7. 互聯網訪問
- 10.8. 日期和時間
- 10.9. 數據壓縮
- 10.10. 性能度量
- 10.11. 質量控制
- 10.12. “瑞士軍刀”
- 11. 標準庫瀏覽 – Part II
- 11.1. 輸出格式
- 11.2. 模板
- 11.3. 使用二進制數據記錄布局
- 11.4. 多線程
- 11.5. 日志
- 11.6. 弱引用
- 11.7. 列表工具
- 11.8. 十進制浮點數算法
- 12. 接下來?
- 13. 交互式輸入行編輯歷史回溯
- 13.1. 行編輯
- 13.2. 歷史回溯
- 13.3. 快捷鍵綁定
- 13.4. 其它交互式解釋器
- 14. 浮點數算法:爭議和限制
- 14.1. 表達錯誤
- 15. 附錄
- 15.1. 交互模式