- Python大學實用教程
- 齊偉
- 5428字
- 2021-01-22 18:49:50
3.2 數字
數字,是任何高級語言都不可缺少的東西,而且任何高級語言都支持數字的計算。Python中的數字也是最基本的對象之一,所以它是本教程中研究的第一個對象。
3.2.1 整數
數學中的整數我們都熟悉了,那么,在Python中如何表示整數(integer)呢?
進入到Python 交互模式中,輸入以下內容。

在數學中,3是屬于“整數”類型中的一個數字。那么,在Python中,3是什么類型中的數字呢?可以用type(3)這種方式來查看(見圖3-2-1)。<class 'int'>是type(3)的返回值,表明數字3的類型是int,即integer(整數)。也就是說,在Python中有一種對象類型稱為整數(或者“整數型”),用符號表示就是int。數學中學過的整數3就是這種類型中的一個對象。

圖3-2-1 分解type(3)的使用方式

使用不完全歸納方法,得到這樣的結論:數學中的所有整數值在Python中都是整數類型(int)。
注意,讀者在閱讀其他文獻的時候,或許會遇到“長整數型”的說法,即較大的整數。在現在Python版本中已經取消了這種類型,統一命名為“整數型”。
剛才使用的type函數在Python中被稱為“內置函數”,本章討論的是“內置對象”。所謂“內置”,就是當Python環境配置好后,相應的東西本地計算機已經有了。所有“內置”的在Python中都可以直接使用,不需要開發者來定義。比如“內置函數”,開發者只需了解函數的使用方法即可,不需要定義這類函數。
那么,如何了解“內置函數”的使用方法呢?
3.2.2 查看文檔
“內置函數”(built-in functions)的所有使用方法都在Python幫助文檔中——幫助文檔中不僅包含“內置函數”,還包含其他幫助內容。
閱讀Python幫助文檔的方法有兩種。一種是訪問官方網站,通過網站查看官方文檔(見圖3-2-2),進入到https://docs.python.org/3/library/functions.html頁面,可以看到Python所有內置函數以及該函數的使用文檔(見圖3-2-3)。
除了看在線文檔,還可以看本地的幫助文檔。實現這個操作要用另一個內置函數help。

在Python交互模式下這樣輸入,然后按Enter鍵,顯示圖3-2-4所示的內容(屏幕上顯示的部分內容)。

圖3-2-2 由官方網站進入幫助文檔

圖3-2-3 Python內置函數幫助文檔界面

圖3-2-4 type函數的部分幫助文檔內容
顯然,這是一種簡單的方法,特別推薦使用。
本節只研究type(object) -> the object's type,其他使用方法暫存。
? type:函數名,后面緊跟“( )”。
? object:表示參數是一個對象。
? -> the object's type:表示這個函數的返回值是對象的類型。
當閱讀完文檔內容,按鍵盤上的q鍵,就可以退回到交互模式中。
help函數是研習Python經常用到的一種方式,用來查看聯機文檔非常方便。請讀者習慣使用,并能夠耐心閱讀文檔。
3.2.3 浮點數
對于數字,除了“整數”,還有“小數”,在Python中怎么表示呢?
進入到Python 的交互模式中,按照下面的方式操作。

在Python 中寫“小數”與在數學中的表現形式一樣,如果查看它的類型,返回值不是“decimal”(小數),而是“float”(翻譯為“浮點數”)。其實不僅是Python,很多高級語言都是如此。但是不能把小數都稱為“浮點數”,因為還有“定點數”。顯然,“浮(動)”和“(固)定”是相反的。關于“定點數”和“浮點數”的詳細內容,建議讀者自行查閱有關資料進行學習,此處不詳述。
至此,我們已經學習了兩種內置對象類型:整數和浮點數。注意,在用type函數查看數字所屬類型的時候,返回值的完整形式是“<class'int'>”或“<class'float'>”,其中class也有其他含義,第6章將對此闡述。讀者姑且知道“int和float既是對象又是對象類型”。

觀察上面的操作,能得到什么結論?
? 觀察1:int函數實現了把浮點數轉化為整數的作用,并且是截取整數,而不是四舍五入。
? 觀察2:float函數實現了把整數轉化為浮點數的作用。
浮點數類型的對象3.0和整數類型的對象3是同一個數嗎?上面這種提問,在數學中或許容易回答,但是在Python中就沒那么簡單了。兩個分屬于不同類型的對象能一樣嗎?比如,屬于“動物”類型的“張三”(此姓名純屬虛構,如有雷同實屬巧合)和屬于“植物”類型的“香樟樹”肯定不一樣。以此類推,“3”和“3.0”應該不是同一個數了。
Python中,兩個對象是否為“同一個”有嚴格的判斷標準,就是看它們的內存地址是否相同——每個對象,在計算機內存中都會有相應的地址編號。查看對象內存地址的方式是使用內置函數id。請讀者在交互模式中使用help(id)查看此函數幫助文檔。

id函數的返回值是參數對象的內存地址。如上面操作所示,兩個對象的內存地址不同,則說明它們是不同的對象。
綜上所述:int和float除了表示類型和類別,還能夠實現對象的類型轉化。
當然,對象的類型轉化是有條件的,不是任何類型的對象都能夠進行轉化。
3.2.4 變量
數學中已經熟悉了“變量”這個名詞,在Python中同樣需要“變量”。Python中的變量(variable)不是孤立存在的,而是依附在對象上的。例如:

在“x=5”中,x是變量,5是整數類型的對象,通過“=”把x和5建立了一種關系。

這里依然是變量x,它又與浮點數類型的對象“6.3”建立了關系。
以上操作過程中,并沒有規定變量x必須跟什么類型的對象建立關系,也沒有規定變量x是什么類型,而是想要讓變量與某個對象建立關系,就使用“=”實現關系的建立。這樣的關系被稱為“引用”,即可以表述為變量x與對象5(或者對象6.3)建立了“引用關系”。
發揮個人的想象力,形象地理解這種引用關系。把“對象”想象成某個實在的物體,而變量就是一枚標簽,這枚標簽可以貼到這個對象(物體)上(如x=5),也可以隨時取下來貼到另一個對象(物體)上(如同換成了x=6.3)。
這樣來看,標簽就不需要有什么類型之分了,只要有不同的名字即可。如同上面所完成的操作那樣,沒有給變量x規定為某種對象類型。這就應了Python中一個重要的觀點:對象有類型,變量無類型。
變量沒有類型,它也不能被稱為對象,所以無法獨立存在。

變量必須引用一個對象,才有存在的意義。不然它不被Python認可,就會顯示一種名為NameError的錯誤類型。
當變量引用了對象之后,變量就代表了那個對象。

變量x雖然是對象“6.3”的代表,但是這個代表也有不牢靠的時候。當它代表了其他對象(與其他對象建立了引用關系)時,這里的“6.3”就成為“沒有代表”的對象了,會被Python認為是垃圾,并自動回收。
在數學中,通常習慣用x、y之類的單個字符表示變量。但是在高級語言編程中,這樣的變量不受歡迎。Python中對變量(嚴格說是普通變量)命名的基本規則如下:
? 變量名稱由小寫字母、數字和下劃線組成,且不以數字開頭。
? 不使用保留字(關鍵字)。
? 單詞之間用單個下劃線連接。
? 使用有意義的單詞。
命名規則中提到了“保留字(關鍵字)”,怎么知道Python有哪些保留字呢?
在交互模式中執行下面的操作:


可以先不用理解操作的意義,重點看得到的返回值,里面所有的單詞都是Python的保留字,請在命名變量時,不要使用這些保留字。
【例題3-2-1】 通過操作,確認哪些變量命名合法。
代碼示例:

不合法的變量命名會被顯示SyntaxError錯誤。
3.2.5 簡單的計算
有了數字,就可以利用這些數字做簡單的運算了,如數學中常見的加、減、乘、除四則運算。

注意觀察這種寫法,在“a=10”與“b=2.5”之間用英文狀態下的“;”分割,其效果等價于下面的寫法。

下面讓變量a和b代表它們各自引用的對象參與運算。

注意,所有的運算符號都是英文狀態下輸入的,特別是乘號不要寫成“×”。
Python中的除法比上面三種運算稍復雜,表示相除的符號是英文狀態的“/”。進入Python交互模式后,練習下面的運算:


除了可以使用“/”符號進行除法運算,還可以使用“//”符號得到兩個數相除的商。

“商”肯定是一個整數,并且這個整數不是“/”操作之后得到的結果進行四舍五入(2.5四舍五入后結果是3),通俗地說是“取整”。兩個數字相除,除了“商”,還有“余數”,在Python中也提供了計算余數的符號。

除了運算符號,內置函數divmod能夠同時獲得商和余數。

在Python中,數字之間的加、減、乘、除運算與數學中的四則運算的規則是一樣的。

除了四則運算,Python也提供了其他簡單運算的方式。比如:

雖然Python(也可以說是計算機)擅長計算,但是有時候會遇到看似難以理解的現象。

這幾個簡單的運算為什么不能得到精確的結果呢?原因在于十進制數和二進制數的轉換。計算機用二進制數進行計算,但在上面的例子中輸入的是十進制數,所以計算機需要把十進制的數轉化為二進制數,再進行計算。但是,在將類似0.1這樣的浮點數轉化為二進制數時,有時候就出現問題了。
0.1轉化為二進制是:0.0001100110011001100110011001100110011001100110011…
0.1轉化為二進制數后,不會精確等于十進制數的0.1。同時,計算機存儲的位數是有限制的,所以出現了上述現象。
這種問題不僅在Python中會遇到,在所有支持浮點數運算的編程語言中都會遇到,這不是Python的Bug。
明白了這種問題產生的原因后,該怎么解決呢?就Python的浮點數運算而言,大多數計算機每次計算誤差不超過1/253。對于大多數任務來說,這已經足夠了,但是要謹記,這不是十進制算法,每個浮點數計算可能帶來一個新的舍入錯誤。
一般情況下,只要簡單地將最終顯示的結果“四舍五入”到所期望的十進制位數,就會得到滿意的最終結果。
實現“四舍五入”可以使用內置函數round,如圖3-2-5所示。在Python交互模式下,可以通過help(round)來獲取完整的函數幫助文檔內容。

圖3-2-5 round()函數使用方法示意
但是,round()函數也不能幸免于十進制和二進制轉化的問題。

這類問題的徹底解決還有賴于其他工具。請見3.2.7節的相關內容。
在數學上,經常用科學計數法表示一些比較大的數字,如12000寫作1.2×104。在Python中也可以使用科學計數法,只不過寫法有區別。

1.2e4即表示1.2×104。
【例題3-2-2】 雞兔同籠,頭35個,腳94只,問雞、兔各多少?
代碼示例

3.2.6 math標準庫
在數值運算中,除了前面的簡單運算,還有如計算對數、正弦、余弦等初等函數的各種運算。但是在Python的內置函數中沒有這些函數。
因為這些初等函數也是常用的,所以Python提供了標準庫來滿足需要。Python標準庫是隨Python附帶安裝的,包含很多常用的模塊(關于“模塊”,請見第7章),此處要使用的math就是標準庫中的一個模塊。


這里顯示出了math模塊提供的所有函數。可以使用help函數查看聯機幫助文檔。

例如,計算數學表達式sin+lg5e2,并且結果保留2位小數。

應用math模塊,再結合前面已學和基本的初等數學知識,就能夠完成大多數初等數學的運算了。盡管如此,運算中還存在一些問題尚待解決。比如:

還有,前面提到的十進制和二進制轉化引起的計算結果不精確問題。所以,必須需要其他工具。
3.2.7 解決“異常”
前面使用標準庫中的math模塊解決了初等數學的函數問題,為了滿足運算的其他要求,Python標準庫中還有其他計算相關的模塊。比如,decimal實現了十進制數精確運算。

類似“10/3”的計算可以使用標準庫中的fractions模塊,實現基于有理數的運算。

上述計算結果雖然不是浮點數和整數類型,但是依然能夠參與數學運算。

注意,下面的方式是不支持的。

關于計算,Python中能夠使用的工具也不僅限于本書介紹的這些,還有諸如NumPy、SciPy等科學計算的專門工具。
【例題3-2-3】 假設兩個人,一個人的質量是70kg,另一個人的質量是50kg,當兩人相距0.5米的時候,它們之間的引力大小是多少?(G=6.67×10-11m3kg-1s-2)
代碼示例

計算表明,這兩個人之間的引力大小是9.3×10-7N,僅相當于大約0.095毫克的物體的重力。
本來,數學中的數字沒有最大值,但是因為計算機本身的結構問題,在編程語言中的數字不是無限大的。
3.2.8 溢出
正如讀者已知,計算機在計算的時候要把十進制的數值轉化為二進制的。比如:

在有的語言中,整數有位數的限制,如C語言中26位的短整型、32位的長整型等。在這種情況下,如果計算結果超出了給定位數表示的數值范圍,就出現了“整數溢出”的現象。而Python中沒有位數的限制,或者說Python中的整數是任意精度,所以可以表示任意大的整數了(僅受制于內存)。

請讀者自己調試,顯示變量a所引用的數字,它是一個3011位的整數。
但是,如果遇到了浮點數參與運算,則要小心“浮點數溢出”了。

【例題3-2-4】 “夜黑佯謬”,又稱為“奧爾伯斯佯謬”,是由德國天文學家奧爾伯斯于1823年提出的,其主要結論是“晚上應該是光亮的而不是黑暗的”。因為計算表明,不論白天和晚上,地球上任何一點得到的來自宇宙中恒星的亮度都是無窮大。不過,這個結論并不符合觀察的事實,我們看到的夜空是黑暗的,所以奧爾伯斯宣布這是一個需要解決的佯謬。(更詳細的內容請閱讀http://blog.sciencenet.cn/blog-677221-921097.html)
這里涉及了“無窮大”,在數學中用符號∞表示,在Python中如何表示?
代碼示例


3.2.9 運算優先級
從小學數學開始,就研究運算優先級的問題,如四則運算中的“先乘除,后加減”說明乘法、除法的優先級要高于加減法。同一級別的運算按照“從左到右”的順序進行計算。
表3-2-1列出了Python 中的各種運算的優先級順序。
表3-2-1 運算符的優先級

表3-2-1按照優先級從低到高的順序列出了Python中的常用運算符。雖然有很多還不知道是怎么回事,不過此處先列出來,等以后用到的時候可以回來查看。當然,不需要記憶,因為與數學中的規則完全一樣。在復雜的表達式中,使用括號能夠讓表達式的可讀性更強。
在程序中,可讀性是非常重要的。
3.2.10 一個簡單的程序
在2.2.5節中已經寫過了一個簡單的程序(文件hello.py)。至今已經學習過一些數值計算了,就可以把程序寫得比hello.py復雜一些了。
【例題3-2-5】 已知兩個力,F1=20N,F2=10N,這兩個力的方向夾角是60°,計算兩個力的合力大小和方向。
解題思路
用中學物理知識解決這個問題,即將兩個力放到一個直角坐標系中,利用正交分解法進行計算。
代碼示例

這段程序的開始部分用三對單引號(或者用三對雙引號)包裹著一些文字,這些內容是對本程序文件的說明(簡稱“程序文檔”),在執行這個程序文件的時候,計算機忽略它。程序文檔之后的各行語句才是計算機要執行的內容。
因為每行語句的含義都是前述各節知識所講授過的,所以不再贅述。建議讀者在每行的空白處寫下對該行代碼的注釋,說明其作用。這就是所謂的“閱讀代碼”。“閱讀代碼”是提升個人編程水平的一種重要方式。
文件保存之后,用下面的方式運行此程序。

如此這般,這個程序就運行起來了。誠然,這里還是非常簡單的程序,畢竟只學習了一種類型的對象。要想編寫復雜的程序,還要繼續學習更多的知識。
- Oracle WebLogic Server 12c:First Look
- jQuery Mobile Web Development Essentials(Third Edition)
- Boost C++ Application Development Cookbook(Second Edition)
- AngularJS Web Application Development Blueprints
- 營銷數據科學:用R和Python進行預測分析的建模技術
- Easy Web Development with WaveMaker
- Mastering Drupal 8 Views
- Java系統化項目開發教程
- Troubleshooting Citrix XenApp?
- Java 9 Programming By Example
- 工業機器人離線編程
- 從0到1:HTML5 Canvas動畫開發
- Java7程序設計入門經典
- 大規模語言模型開發基礎與實踐
- 安卓工程師教你玩轉Android