### 7.1.1 面向過程觀點
我們用一個簡單程序來說明傳統程序設計的思維方式。
【程序 7.1】eg7_1.py
```
x = 1
y = 2
z = x + y
print z
```
到目前為止,我們在編程時基本上都是這樣思考的:先用特定數據類型的常量或變量來 表示數據(如程序 7.1 中分別存入變量 x 和 y 的整數類型值 1 和 2),然后再利用合適的操作(如程序 7.1 中的加法運算“+”)按一定的步驟來處理數據。在這種思考方式下,數據和對 數據的操作被看作是分離的兩件事情:數據只是信息的表示,不表達任何操作,在程序中處 于“被動”地位;而對數據的操作在程序中則處于“主動”地位,是驅動程序實現特定功能 的力量。程序 7.1 可視為用操作“+”主動地去處理被動的數據 x 和 y,從而實現加法功能。 圖 7.1 以一個比喻來形象地展示這種觀點:數據與操作之間的關系正如心與箭的關系——沒 有丘比特的箭,兩顆心是不會彼此連結的。

圖 7.1 傳統觀點:數據與操作分離
在數據與操作分離的傳統觀點下,通常以算法過程的設計為主線來展開程序設計,故可稱為以過程為中心的程序設計。以求解一元二次方程的程序 3.6 為例,數據(系數 a、b、c) 明確后,需要精心設計的是處理這些數據的操作過程:先計算判別式 b2-4ac,然后根據判別 式的值判斷方程是否有解,有解的情況下再利用公式求解,最后輸出結果。
在以操作為中心的設計理念下,程序中的數據有時對整個操作過程都是公開的,可以被 操作過程中的每個步驟訪問、處理。例如,假設程序 7.1 的操作不是單一的加法,而是在加法操作(第 3 行)之后還有兩個操作:
```
w = x – y
z = z * w
```
可以看出,數據(x、y、z、w)對程序中所有的操作都是公開的。這時,程序中對數據的訪問不受任何控制,非常容易出現錯誤的操作。
當然,實際的應用程序不會像程序 7.1 這樣簡單。復雜程序中不但數據復雜,而且對數 據的操作也非常復雜,所有操作可能形成漫長而曲折的過程。為了應付操作過程的復雜性, 按照第 4 章所介紹的模塊化編程思想,可以將復雜操作過程組織成為若干個較小的模塊—— 函數,每個函數實現一個相對簡單的、單一的功能。例如下面這個“復雜”程序①:
【程序 7.2】eg7_2.py
```
def op1(a,b):
return a * a - b * b
def op2(a,b):
return a ** b + b ** a
x = 1
y = 2
z = 3
result1 = op1(x,y)
result2 = op2(x,z)
print result1 + result2
```
從一個更抽象的層次看,每個函數其實相當于一個操作。與程序 7.1 相比,程序 7.2 對 更多的數據(x、y、z)進行更復雜的操作:先執行 op1 操作,再執行 op2 操作,最后輸出結 果。無論是程序 7.1 的簡單操作“+”還是程序 7.2 的復雜操作“op1”、“op2”,它們都是“對 數據的操作”,仍然屬于“數據與操作相互分離”的思考方式,整個程序仍然是對數據按一定 順序執行操作的過程。
不過,作為高抽象級別操作的函數具有一定的訪問控制能力。函數就像一個提供某種功 能的黑箱,使用者需要的只是它的功能,并不需要知曉它內部是如何實現功能的。函數內部 處理的數據不是對整個程序都公開的數據,一個函數不能訪問另一個函數內部的數據。然而, 程序中仍然有一些全局數據是對所有操作(包括函數)公開的,仍然存在前述訪問控制問題, 例如程序 7.2 中的兩個函數 op1 和 op2 都在處理數據 x。
總之,不管程序是簡單還是復雜,不管操作是語句級的還是函數級的,傳統程序設計都 是按照數據與操作分離的觀點,以過程為中心展開程序設計的。在這種面向過程的編程范型 中,強調的是對數據的操作過程,程序員思考的主要問題是數據如何表示、對各數據執行什 么操作以及各操作的先后順序如何安排。當程序很復雜時,可以采用自頂向下設計和模塊化 設計方法,將使用低級別操作的復雜過程設計成使用高級別操作的簡單過程。
要指出的是,基于數據與操作分離觀點的面向過程編程具有其內在的局限性,在處理某 些復雜問題和系統時顯得不合適。例如,圖形用戶界面(GUI)程序②就不屬于“對給定數據,
> ① 這個程序自然一點也不復雜,但不妨礙它可以用于說明復雜操作的問題。
> ② 詳見第 8 章。
按特定次序對數據進行操作,操作完畢程序即告結束”的程序執行模式。以 Word 程序為例, 當啟動 Word 打開文檔(即程序數據)之后,接下去對數據如何操作呢?Word 程序并不知道 該做什么,它只能等在那里。接下去用戶可能用鍵盤輸入文本,也可能用鼠標點擊菜單或工 具欄進行存盤或打印,總之用戶需要通過某種交互事件來告訴 Word 程序該如何操作數據, 一個操作完成后 Word 又進入等待狀態。可見,GUI 程序屬于“先建立一個圖形界面,然后 等待來自用戶的不可預知的事件發生;事件發生后才導致執行某些操作,事件處理完畢又回 到等待狀態”這樣一種程序執行模式,程序從啟動到結束的具體執行過程取決于事件發生的 順序,不像傳統程序那樣預定義了執行順序。
為了適應 GUI 程序這類沒有明確的預定義操作次序、靠不確定的事件來驅動的程序和系 統的開發,提高開發效率和質量,計算機科學家提出了一種新的觀點來看待數據與操作之間 的關系,即面向對象的觀點。
- 前言
- 第 1 章 計算與計算思維
- 1.1 什么是計算?
- 1.1.1 計算機與計算
- 1.1.2 計算機語言
- 1.1.3 算法
- 1.1.4 實現
- 1.2 什么是計算思維?
- 1.2.1 計算思維的基本原則
- 1.2.2 計算思維的具體例子
- 1.2.3 日常生活中的計算思維
- 1.2.4 計算思維對其他學科的影響
- 1.3 初識 Python
- 1.3.1 Python 簡介
- 1.3.2 第一個程序
- 1.3.3 程序的執行方式
- 1.3.4 Python 語言的基本成分
- 1.4 程序排錯
- 1.5 練習
- 第 2 章 用數據表示現實世界
- 2.1 數據和數據類型
- 2.1.1 數據是對現實的抽象
- 2.1.1 常量與變量
- 2.1.2 數據類型
- 2.1.3 Python 的動態類型*
- 2.2 數值類型
- 2.2.1 整數類型 int
- 2.2.2 長整數類型 long
- 2.2.3 浮點數類型 float
- 2.2.4 數學庫模塊 math
- 2.2.5 復數類型 complex*
- 2.3 字符串類型 str
- 2.3.1 字符串類型的字面值形式
- 2.3.2 字符串類型的操作
- 2.3.3 字符的機內表示
- 2.3.4 字符串類型與其他類型的轉換
- 2.3.5 字符串庫 string
- 2.4 布爾類型 bool
- 2.4.1 關系運算
- 2.4.2 邏輯運算
- 2.4.3 布爾代數運算定律*
- 2.4.4 Python 中真假的表示與計算*
- 2.5 列表和元組類型
- 2.5.1 列表類型 list
- 2.5.2 元組類型 tuple
- 2.6 數據的輸入和輸出
- 2.6.1 數據的輸入
- 2.6.2 數據的輸出
- 2.6.3 格式化輸出
- 2.7 編程案例:查找問題
- 2.8 練習
- 第 3 章 數據處理的流程控制
- 3.1 順序控制結構
- 3.2 分支控制結構
- 3.2.1 單分支結構
- 3.2.2 兩路分支結構
- 3.2.3 多路分支結構
- 3.3 異常處理
- 3.3.1 傳統的錯誤檢測方法
- 3.3.2 傳統錯誤檢測方法的缺點
- 3.3.3 異常處理機制
- 3.4 循環控制結構
- 3.4.1 for 循環
- 3.4.2 while 循環
- 3.4.3 循環的非正常中斷
- 3.4.4 嵌套循環
- 3.5 結構化程序設計
- 3.5.1 程序開發過程
- 3.5.2 結構化程序設計的基本內容
- 3.6 編程案例:如何求 n 個數據的最大值?
- 3.6.1 幾種解題策略
- 3.6.2 經驗總結
- 3.7 Python 布爾表達式用作控制結構*
- 3.8 練習
- 第 4 章 模塊化編程
- 4.1 模塊化編程基本概念
- 4.1.1 模塊化設計概述
- 4.1.2 模塊化編程
- 4.1.3 編程語言對模塊化編程的支持
- 4.2 Python 語言中的函數
- 4.2.1 用函數減少重復代碼 首先看一個簡單的用字符畫一棵樹的程序:
- 4.2.2 用函數改善程序結構
- 4.2.3 用函數增強程序的通用性
- 4.2.4 小結:函數的定義與調用
- 4.2.5 變量的作用域
- 4.2.6 函數的返回值
- 4.3 自頂向下設計
- 4.3.1 頂層設計
- 4.3.2 第二層設計
- 4.3.3 第三層設計
- 4.3.4 第四層設計
- 4.3.5 自底向上實現與單元測試
- 4.3.6 開發過程小結
- 4.4 Python 模塊*
- 4.4.1 模塊的創建和使用
- 4.4.2 Python 程序架構
- 4.4.3 標準庫模塊
- 4.4.4 模塊的有條件執行
- 4.5 練習
- 第 5 章 圖形編程
- 5.1 概述
- 5.1.1 計算可視化
- 5.1.2 圖形是復雜數據
- 5.1.3 用對象表示復雜數據
- 5.2 Tkinter 圖形編程
- 5.2.1 導入模塊及創建根窗口
- 5.2.2 創建畫布
- 5.2.3 在畫布上繪圖
- 5.2.4 圖形的事件處理
- 5.3 編程案例
- 5.3.1 統計圖表
- 5.3.2 計算機動畫
- 5.4 軟件的層次化設計:一個案例
- 5.4.1 層次化體系結構
- 5.4.2 案例:圖形庫 graphics
- 5.4.3 graphics 與面向對象
- 5.5 練習
- 第 6 章 大量數據的表示和處理
- 6.1 概述
- 6.2 有序的數據集合體
- 6.2.1 字符串
- 6.2.2 列表
- 6.2.3 元組
- 6.3 無序的數據集合體
- 6.3.1 集合
- 6.3.2 字典
- 6.4 文件
- 6.4.1 文件的基本概念
- 6.4.2 文件操作
- 6.4.3 編程案例:文本文件分析
- 6.4.4 緩沖
- 6.4.5 二進制文件與隨機存取*
- 6.5 幾種高級數據結構*
- 6.5.1 鏈表
- 6.5.2 堆棧
- 6.5.3 隊列
- 6.6 練習
- 第 7 章 面向對象思想與編程
- 7.1 數據與操作:兩種觀點
- 7.1.1 面向過程觀點
- 7.1.2 面向對象觀點
- 7.1.3 類是類型概念的發展
- 7.2 面向對象編程
- 7.2.1 類的定義
- 7.2.2 對象的創建
- 7.2.3 對象方法的調用
- 7.2.4 編程實例:模擬炮彈飛行
- 7.2.5 類與模塊化
- 7.2.6 對象的集合體
- 7.3 超類與子類*
- 7.3.1 繼承
- 7.3.2 覆寫
- 7.3.3 多態性
- 7.4 面向對象設計*
- 7.5 練習
- 第 8 章 圖形用戶界面
- 8.1 圖形用戶界面概述
- 8.1.1 程序的用戶界面
- 8.1.2 圖形界面的組成
- 8.1.3 事件驅動
- 8.2 GUI 編程
- 8.2.1 UI 編程概述
- 8.2.2 初識 Tkinter
- 8.2.3 常見 GUI 構件的用法
- 8.2.4 布局
- 8.2.5 對話框*
- 8.3 Tkinter 事件驅動編程
- 8.3.1 事件和事件對象
- 8.3.2 事件處理
- 8.4 模型-視圖設計方法
- 8.4.1 將 GUI 應用程序封裝成對象
- 8.4.2 模型與視圖
- 8.4.3 編程案例:匯率換算器
- 8.5 練習
- 第 9 章 模擬與并發
- 9.1 模擬
- 9.1.1 計算機建模
- 9.1.2 隨機問題的建模與模擬
- 9.1.3 編程案例:乒乓球比賽模擬
- 9.2 原型法
- 9.3 并行計算*
- 9.3.1 串行、并發與并行
- 9.3.2 進程與線程
- 9.3.3 多線程編程的應用
- 9.3.4 Python 多線程編程
- 9.3.5 小結
- 9.4 練習
- 第 10 章 算法設計和分析
- 10.1 枚舉法
- 10.2 遞歸
- 10.3 分治法
- 10.4 貪心法
- 10.5 算法分析
- 10.5.1 算法復雜度
- 10.5.2 算法分析實例
- 10.6 不可計算的問題
- 10.7 練習
- 第 11 章 計算+X
- 11.1 計算數學
- 11.2 生物信息學
- 11.3 計算物理學
- 11.4 計算化學
- 11.5 計算經濟學
- 11.6 練習
- 附錄
- 1 Python 異常處理參考
- 2 Tkinter 畫布方法
- 3 Tkinter 編程參考
- 3.1 構件屬性值的設置
- 3.2 構件的標準屬性
- 3.3 各種構件的屬性
- 3.4 對話框
- 3.5 事件
- 參考文獻