學習python


因為遇到了一些問題,所以打算從頭學起,希望可以真正了解問題點在哪裡,也希望可以幫到其他人

先從最基本的名稱、物件、型別、指派


命名規則

當我們要在程式裡取名時,必須遵守Python的規則 :

1. 可使用英文字母小寫 a ~ z 大寫 A ~ Z 數字 0 ~ 9 底線 _

2. 第一個字不能是數字

Python的名稱區分大小寫,所以money跟Money代表不同的名稱,不過有些識別字被Python拿去用了,稱為保留字(reserved word)或關鍵字(keyword),代表特定的意思,有其特殊用途,不能拿來命名,下圖為Python保留字



串列(list)

除了整數(int)、浮點數(float)、字串(str)外;叫做串列(list),此種型別可放入任何型別的物件。想建立串列物件時,語法是方括號[],放入想含有的物件,範例


當我們說串列內可存放物件時,是讓該串列能以索引的方是指向別的物件


可變與不可變

型別int、float、str的物件,都有不可變(immutable)的特性,一旦建立之後,其值就無法更動;可以讓名稱轉而指向別的物件,但無法修改不可變物件



別名

因為Python有不可變(int,float,str)跟可變(list)物件之分,而且名稱跟物件其實是獨立的兩樣東西,所以要注意當兩個(或以上)的名稱都指向同一個物件時的狀況,別名(alias)也叫做共享參考(shared reference)




tuple(元組)

就是不可變的list(串列),須使用小括號()放入想含有的物件


運算式

算術運算子

包括(+, -, , /, %, //, ),*是乘法,是冪次方,/是除法,//是地板除法,%餘數運算子,來看例子


str字串跟list與tuple也可以使用 + , * 作運算



比較運算子

<, <=, >, >=, !=, <>, == :作大小比較

in, not in :檢查某元素是否在容器型物件裡頭

is , is not :判斷兩個物件是否為同一個

結果會產生bool(布林)型別的物件,True與False


邏輯運算子

and, or, not ,當and運算時,只有左右兩邊皆為True時,運算結果才會是True,其餘皆為False; or則只要有一個為True,得到的結果就是True,not則 是反轉真假值


一般的數值運算子,如(+, , /)等等,其優先順序都高於比較運算子,如(<=, !=, is not)等


述句

是Python程式裡最小最基本的執行單位,每種數據都有其獨特的語法和語意,不符合述句語法的話,就是不合法的程式碼,就不能被直譯器執行


指派述句


多重指派


序列指派


增強型指派述句


if 條件判斷述句

if述句可根據運算式結果(True或False),作為條件來判斷應該執行哪部分的程式碼,控制走向,稱此類的述句為程式流程控制,if, elif, else那一行的最後面要加上冒號(:),表是後面將接著一組程式述句,而裡頭的述句必須縮排。



Python因使用縮排來標示程式碼的層級,不同於C / C++ / Java / C# / JavaScript 以大括號{}來包住程式碼的方式


pass述句

pass述句什麼也不做,因為根據Python語法,有時須放進述句,但不需要或不知道該寫什麼,就放pass述句,這樣便可符合語法,否則將發生錯誤


while迴圈述句


for迴圈述句


break述句與continue述句


述句總覽表


函式

定義函式的語法 def 函式名稱 (參數0, 參數1, ......):



參數

呼叫函式時可傳入參數,這個動作跟指派幾乎一模一樣,所謂傳入參數,也就是說呼叫方把某物件指派給參數的名稱,要小心的是,如果參數是可變物件,那麼函式拿到該參數後,也可以改變該物件


return述句



可視範圍(scope)

名稱的可視範圍,決定了在程式的什麼地方能夠看到該名稱,進而存取該名稱指向的物件,在尚未定義函式的程式範圍裡,所有名稱通通都擁有[全域(global)]可視範圍,這些名稱定義在程式最高最外圍的地方,如下圖 a ,b, foo, x, y ,一旦定義後,就能存取名稱指向的物件,簡稱為(全域名稱);而定義在函式範圍裡的名稱(包括參數),如下圖的n, m,只擁有[區域(local)]可視範圍,只有在該函式內才看得到這些名稱,簡稱(區域名稱)。



在函式(區域)裡,雖可以自由取用全域名稱,但只能讀 不能寫,該如何把新物件指派給全域名稱呢?一但在函式裡把全域名稱放在指派述句的左邊,會產生區域名稱,而不是把新物件指派給全域名稱。辦法是使用(global述句),便可在函式內重新指派全域名稱到新物件



內建函式

跟算術相關的內建函式

求總合函式sum(), 求串列長度len()

range()是建立出(能提供一連串東西的物件),可用在for迴圈

abs()絕對值, pow()冪次方,等同於**運算子, round()四捨五入到小數點後第二位, divmod()商和餘數



跟邏輯相關的內建函式

all(), any()



有些可得知關於物件的資訊

id(), type()物件的型別, callable()是不是可被呼叫



模組(module)

當Python程式越寫越大,不可能將所有程式碼都放在一起,而應該經適當的切割,根據功能特色劃分成一個又一個的模組(module),由主程式匯入取用。Python模組可以是Python程式碼 也可以是C語言(或其他)的程式碼

我們先建立兩個檔案,一個是主程式檔,一個是模組檔,將這兩個檔案放在同一個目錄裡(檔名自取),不一定要跟下圖一樣



在主程式檔裡,我們使用了(import 述句)匯入模組,例如(import 模組檔名)在import後加上模組名,注意,不需要加上 .py副檔名 。



在主執行檔裡使用(import 述句)的作用,就如同去執行模組檔一樣,只不過執行後得到的名稱,會被放入模組物件裡,因為Python 模組物件具有命名空間(namespace)的功能,可存放東西(名稱); 匯入後,可使用(模組名.名稱)的語法,去存取模組裡的名稱(與其指向的物件)。


import 述句還有其它變形,把 (import 模組名) 改為(from 模組名 import * )的話,等於直接把模組名裡的名稱,直接匯到主執行檔的全域範圍裡,就能直接使用(pi, gcd, factorial)等名稱,不需要再加(模組名.),不過這種匯入方式比較容易出問題,萬一模組名裡的名稱跟你執行檔裡的名稱一樣? 或匯入多個模組,模組名之間重疊? 可以改用(from 模組名 import 名稱),明確的指定想匯入的名稱。


另一種import 述句變形是(import 模組名 as m),m是為模組新取的較短名稱,然後以(模組名.名稱)的語法,來存取模組內的名稱,例如: (m.pi) (m.gcd)。


標準程式庫模組

在模組keyword裡,串列kwlist含有Python的保留字,而函式iskeyword可判定某字串是否為保留字



有個模組含有Python全部的內建名稱,包括函式、常數、異常等,名稱是__builtins__,呼叫內建函式dir可列出模組內容。2.x版是模組__builtin__、3.x版是模組builtins


模組math裡含有各種常用的數學函數,如:sqrt(x)計算平方根、pow(x, y)可算出x的y次方、log10(x)可求出x的對數、sin(x)與cos(x)等三角函數、pi與 e 等數學常數


模組random跟隨機亂數相關,提供各種產生亂數的函式,不過Python模組的ranndom提供的是虛擬亂數(pseudo random 或稱假亂數),非真正的亂數,不可用於密碼、加密、安全等方面。這種亂數屬於(亂中有序),若了解其機制與規則,便能知道會產生哪個亂數


模組搜尋路徑

當使用import匯入模組時,Python直譯器會根據一份模組搜尋路徑清單,逐一到路徑裡去找模組,然後載入。透過模組sys的串列path得知模組搜尋路徑


模組之名(name)

模組具備命名空間的功能,可放進名稱,除了各個模組自行提供的常數、函式之外,Python模組預設有一些名稱,其中之一(name),指向代表模組名的字串物件,透過這個名稱,便能判斷.py檔是被當做主程式檔交給直譯器執行,還是當做模組檔被import述句匯入


結論

最重要的重點,是搞懂名稱(name)與物件(object)的概念,以及相關的型別(type)、指派(assignment)、綁定(binding),了解基本知識,並明白在 "Python"裡任何東西都是物件



Comments

comments powered by Disqus