# Python多線程
多線程類似于同時執行多個不同程序,多線程運行有如下優點:
* 使用線程可以把占據長時間的程序中的任務放到后臺去處理。
* 用戶界面可以更加吸引人,這樣比如用戶點擊了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度
* 程序的運行速度可能加快
* 在一些等待的任務實現上如用戶輸入、文件讀寫和網絡收發數據等,線程就比較有用了。在這種情況下我們可以釋放一些珍貴的資源如內存占用等等。
線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口。但是線程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
每個線程都有他自己的一組CPU寄存器,稱為線程的上下文,該上下文反映了線程上次運行該線程的CPU寄存器的狀態。
指令指針和堆棧指針寄存器是線程上下文中兩個最重要的寄存器,線程總是在進程得到上下文中運行的,這些地址都用于標志擁有線程的進程地址空間中的內存。
* 線程可以被搶占(中斷)。
* 在其他線程正在運行時,線程可以暫時擱置(也稱為睡眠) -- 這就是線程的退讓。
## 開始學習Python線程
Python中使用線程有兩種方式:函數或者用類來包裝線程對象。
函數式:調用thread模塊中的start_new_thread()函數來產生新線程。語法如下:
```
thread.start_new_thread ( function, args[, kwargs] )
```
參數說明:
* function - 線程函數。
* args - 傳遞給線程函數的參數,他必須是個tuple類型。
* kwargs - 可選參數。
實例:
```
#!/usr/bin/python
import thread
import time
# 為線程定義一個函數
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print "%s: %s" % ( threadName, time.ctime(time.time()) )
# 創建兩個線程
try:
thread.start_new_thread( print_time, ("Thread-1", 2, ) )
thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
print "Error: unable to start thread"
while 1:
pass
```
執行以上程序輸出結果如下:
```
Thread-1: Thu Jan 22 15:42:17 2009
Thread-1: Thu Jan 22 15:42:19 2009
Thread-2: Thu Jan 22 15:42:19 2009
Thread-1: Thu Jan 22 15:42:21 2009
Thread-2: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:25 2009
Thread-2: Thu Jan 22 15:42:27 2009
Thread-2: Thu Jan 22 15:42:31 2009
Thread-2: Thu Jan 22 15:42:35 2009
```
線程的結束一般依靠線程函數的自然結束;也可以在線程函數中調用thread.exit(),他拋出SystemExit exception,達到退出線程的目的。
## 線程模塊
Python通過兩個標準庫thread和threading提供對線程的支持。thread提供了低級別的、原始的線程以及一個簡單的鎖。
thread 模塊提供的其他方法:
* threading.currentThread(): 返回當前的線程變量。
* threading.enumerate(): 返回一個包含正在運行的線程的list。正在運行指線程啟動后、結束前,不包括啟動前和終止后的線程。
* threading.activeCount(): 返回正在運行的線程數量,與len(threading.enumerate())有相同的結果。
除了使用方法外,線程模塊同樣提供了Thread類來處理線程,Thread類提供了以下方法:
* **run():** 用以表示線程活動的方法。
* **start():**啟動線程活動。
* **join([time]):** 等待至線程中止。這阻塞調用線程直至線程的join() 方法被調用中止-正常退出或者拋出未處理的異常-或者是可選的超時發生。
* **isAlive():** 返回線程是否活動的。
* **getName():** 返回線程名。
* **setName():** 設置線程名。
## 使用Threading模塊創建線程
使用Threading模塊創建線程,直接從threading.Thread繼承,然后重寫__init__方法和run方法:
```
#!/usr/bin/python
import threading
import time
exitFlag = 0
class myThread (threading.Thread): #繼承父類threading.Thread
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self): #把要執行的代碼寫到run函數里面 線程在創建后會直接運行run函數
print "Starting " + self.name
print_time(self.name, self.counter, 5)
print "Exiting " + self.name
def print_time(threadName, delay, counter):
while counter:
if exitFlag:
thread.exit()
time.sleep(delay)
print "%s: %s" % (threadName, time.ctime(time.time()))
counter -= 1
# 創建新線程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 開啟線程
thread1.start()
thread2.start()
print "Exiting Main Thread"
```
以上程序執行結果如下;
```
Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Thu Mar 21 09:10:03 2013
Thread-1: Thu Mar 21 09:10:04 2013
Thread-2: Thu Mar 21 09:10:04 2013
Thread-1: Thu Mar 21 09:10:05 2013
Thread-1: Thu Mar 21 09:10:06 2013
Thread-2: Thu Mar 21 09:10:06 2013
Thread-1: Thu Mar 21 09:10:07 2013
Exiting Thread-1
Thread-2: Thu Mar 21 09:10:08 2013
Thread-2: Thu Mar 21 09:10:10 2013
Thread-2: Thu Mar 21 09:10:12 2013
Exiting Thread-2
```
## 線程同步
如果多個線程共同對某個數據修改,則可能出現不可預料的結果,為了保證數據的正確性,需要對多個線程進行同步。
使用Thread對象的Lock和Rlock可以實現簡單的線程同步,這兩個對象都有acquire方法和release方法,對于那些需要每次只允許一個線程操作的數據,可以將其操作放到acquire和release方法之間。如下:
多線程的優勢在于可以同時運行多個任務(至少感覺起來是這樣)。但是當線程需要共享數據時,可能存在數據不同步的問題。
考慮這樣一種情況:一個列表里所有元素都是0,線程"set"從后向前把所有元素改成1,而線程"print"負責從前往后讀取列表并打印。
那么,可能線程"set"開始改的時候,線程"print"便來打印列表了,輸出就成了一半0一半1,這就是數據的不同步。為了避免這種情況,引入了鎖的概念。
鎖有兩種狀態——鎖定和未鎖定。每當一個線程比如"set"要訪問共享數據時,必須先獲得鎖定;如果已經有別的線程比如"print"獲得鎖定了,那么就讓線程"set"暫停,也就是同步阻塞;等到線程"print"訪問完畢,釋放鎖以后,再讓線程"set"繼續。
經過這樣的處理,打印列表時要么全部輸出0,要么全部輸出1,不會再出現一半0一半1的尷尬場面。
實例:
```
#!/usr/bin/python
import threading
import time
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print "Starting " + self.name
# 獲得鎖,成功獲得鎖定后返回True
# 可選的timeout參數不填時將一直阻塞直到獲得鎖定
# 否則超時后將返回False
threadLock.acquire()
print_time(self.name, self.counter, 3)
# 釋放鎖
threadLock.release()
def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print "%s: %s" % (threadName, time.ctime(time.time()))
counter -= 1
threadLock = threading.Lock()
threads = []
# 創建新線程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
# 開啟新線程
thread1.start()
thread2.start()
# 添加線程到線程列表
threads.append(thread1)
threads.append(thread2)
# 等待所有線程完成
for t in threads:
t.join()
print "Exiting Main Thread"
```
## 線程優先級隊列( Queue)
Python的Queue模塊中提供了同步的、線程安全的隊列類,包括FIFO(先入先出)隊列Queue,LIFO(后入先出)隊列LifoQueue,和優先級隊列PriorityQueue。這些隊列都實現了鎖原語,能夠在多線程中直接使用。可以使用隊列來實現線程間的同步。
Queue模塊中的常用方法:
* Queue.qsize() 返回隊列的大小
* Queue.empty() 如果隊列為空,返回True,反之False
* Queue.full() 如果隊列滿了,返回True,反之False
* Queue.full 與 maxsize 大小對應
* Queue.get([block[, timeout]])獲取隊列,timeout等待時間
* Queue.get_nowait() 相當Queue.get(False)
* Queue.put(item) 寫入隊列,timeout等待時間
* Queue.put_nowait(item) 相當Queue.put(item, False)
* Queue.task_done() 在完成一項工作之后,Queue.task_done()函數向任務已經完成的隊列發送一個信號
* Queue.join() 實際上意味著等到隊列為空,再執行別的操作
實例:
```
#!/usr/bin/python
import Queue
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print "Starting " + self.name
process_data(self.name, self.q)
print "Exiting " + self.name
def process_data(threadName, q):
while not exitFlag:
queueLock.acquire()
if not workQueue.empty():
data = q.get()
queueLock.release()
print "%s processing %s" % (threadName, data)
else:
queueLock.release()
time.sleep(1)
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1
# 創建新線程
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# 填充隊列
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()
# 等待隊列清空
while not workQueue.empty():
pass
# 通知線程是時候退出
exitFlag = 1
# 等待所有線程完成
for t in threads:
t.join()
print "Exiting Main Thread"
```
以上程序執行結果:
```
Starting Thread-1
Starting Thread-2
Starting Thread-3
Thread-1 processing One
Thread-2 processing Two
Thread-3 processing Three
Thread-1 processing Four
Thread-2 processing Five
Exiting Thread-3
Exiting Thread-1
Exiting Thread-2
Exiting Main Thread
```
# python XML解析
## 什么是XML?
XML 指可擴展標記語言(e**X**tensible **M**arkup **L**anguage)。 你可以通過本站學習[XML教程](/xml/xml-tutorial.html "XML教程")
XML 被設計用來傳輸和存儲數據。
XML是一套定義語義標記的規則,這些標記將文檔分成許多部件并對這些部件加以標識。
它也是元標記語言,即定義了用于定義其他與特定領域有關的、語義的、結構化的標記語言的句法語言。
## python對XML的解析
常見的XML編程接口有DOM和SAX,這兩種接口處理XML文件的方式不同,當然使用場合也不同。
python有三種方法解析XML,SAX,DOM,以及ElementTree:
### 1.SAX (simple API for XML )
pyhton 標準庫包含SAX解析器,SAX用事件驅動模型,通過在解析XML的過程中觸發一個個的事件并調用用戶定義的回調函數來處理XML文件。
### 2.DOM(Document Object Model)
將XML數據在內存中解析成一個樹,通過對樹的操作來操作XML。
### 3.ElementTree(元素樹)
ElementTree就像一個輕量級的DOM,具有方便友好的API。代碼可用性好,速度快,消耗內存少。
**注:**因DOM需要將XML數據映射到內存中的樹,一是比較慢,二是比較耗內存,而SAX流式讀取XML文件,比較快,占用內存少,但需要用戶實現回調函數(handler)。
本章節使用到的XML實例文件movies.xml內容如下:
```
<collection shelf="New Arrivals">
<movie title="Enemy Behind">
<type>War, Thriller</type>
<format>DVD</format>
<year>2003</year>
<rating>PG</rating>
<stars>10</stars>
<description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
<type>Anime, Science Fiction</type>
<format>DVD</format>
<year>1989</year>
<rating>R</rating>
<stars>8</stars>
<description>A schientific fiction</description>
</movie>
<movie title="Trigun">
<type>Anime, Action</type>
<format>DVD</format>
<episodes>4</episodes>
<rating>PG</rating>
<stars>10</stars>
<description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
<type>Comedy</type>
<format>VHS</format>
<rating>PG</rating>
<stars>2</stars>
<description>Viewable boredom</description>
</movie>
</collection>
```
## python使用SAX解析xml
SAX是一種基于事件驅動的API。
利用SAX解析XML文檔牽涉到兩個部分:解析器和事件處理器。
解析器負責讀取XML文檔,并向事件處理器發送事件,如元素開始跟元素結束事件;
而事件處理器則負責對事件作出相應,對傳遞的XML數據進行處理。
<psax適于處理下面的問題:< p="">
* 1、對大型文件進行處理;
* 2、只需要文件的部分內容,或者只需從文件中得到特定信息。
* 3、想建立自己的對象模型的時候。
在python中使用sax方式處理xml要先引入xml.sax中的parse函數,還有xml.sax.handler中的ContentHandler。
### ContentHandler類方法介紹
**characters(content)方法**
調用時機:
從行開始,遇到標簽之前,存在字符,content的值為這些字符串。
從一個標簽,遇到下一個標簽之前, 存在字符,content的值為這些字符串。
從一個標簽,遇到行結束符之前,存在字符,content的值為這些字符串。
標簽可以是開始標簽,也可以是結束標簽。
**startDocument()方法**
文檔啟動的時候調用。
**endDocument()方法**
解析器到達文檔結尾時調用。
**startElement(name, attrs)方法**
遇到XML開始標簽時調用,name是標簽的名字,attrs是標簽的屬性值字典。
**endElement(name)方法**
遇到XML結束標簽時調用。
## make_parser方法
以下方法創建一個新的解析器對象并返回。
```
xml.sax.make_parser( [parser_list] )
```
參數說明:
* **parser_list** - 可選參數,解析器列表
## parser方法
以下方法創建一個 SAX 解析器并解析xml文檔:
```
xml.sax.parse( xmlfile, contenthandler[, errorhandler])
```
參數說明:
* **xmlfile** - xml文件名
* **contenthandler** - 必須是一個ContentHandler的對象
* **errorhandler** - 如果指定該參數,errorhandler必須是一個SAX ErrorHandler對象
## parseString方法
parseString方法創建一個XML解析器并解析xml字符串:
```
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
```
參數說明:
* **xmlstring** - xml字符串
* **contenthandler** - 必須是一個ContentHandler的對象
* **errorhandler** - 如果指定該參數,errorhandler必須是一個SAX ErrorHandler對象
## Python 解析XML實例
```
#!/usr/bin/python
import xml.sax
class MovieHandler( xml.sax.ContentHandler ):
def __init__(self):
self.CurrentData = ""
self.type = ""
self.format = ""
self.year = ""
self.rating = ""
self.stars = ""
self.description = ""
# 元素開始事件處理
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "movie":
print "*****Movie*****"
title = attributes["title"]
print "Title:", title
# 元素結束事件處理
def endElement(self, tag):
if self.CurrentData == "type":
print "Type:", self.type
elif self.CurrentData == "format":
print "Format:", self.format
elif self.CurrentData == "year":
print "Year:", self.year
elif self.CurrentData == "rating":
print "Rating:", self.rating
elif self.CurrentData == "stars":
print "Stars:", self.stars
elif self.CurrentData == "description":
print "Description:", self.description
self.CurrentData = ""
# 內容事件處理
def characters(self, content):
if self.CurrentData == "type":
self.type = content
elif self.CurrentData == "format":
self.format = content
elif self.CurrentData == "year":
self.year = content
elif self.CurrentData == "rating":
self.rating = content
elif self.CurrentData == "stars":
self.stars = content
elif self.CurrentData == "description":
self.description = content
if ( __name__ == "__main__"):
# 創建一個 XMLReader
parser = xml.sax.make_parser()
# turn off namepsaces
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
# 重寫 ContextHandler
Handler = MovieHandler()
parser.setContentHandler( Handler )
parser.parse("movies.xml")
```
以上代碼執行結果如下:
```
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Stars: 8
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Stars: 2
Description: Viewable boredom
```
完整的 SAX API 文檔請查閱[Python SAX APIs](//docs.python.org/library/xml.sax.html)
## 使用xml.dom解析xml
文件對象模型(Document Object Model,簡稱DOM),是W3C組織推薦的處理可擴展置標語言的標準編程接口。
一個 DOM 的解析器在解析一個 XML 文檔時,一次性讀取整個文檔,把文檔中所有元素保存在內存中的一個樹結構里,之后你可以利用DOM 提供的不同的函數來讀取或修改文檔的內容和結構,也可以把修改過的內容寫入xml文件。
python中用xml.dom.minidom來解析xml文件,實例如下:
```
#!/usr/bin/python
from xml.dom.minidom import parse
import xml.dom.minidom
# 使用minidom解析器打開 XML 文檔
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
print "Root element : %s" % collection.getAttribute("shelf")
# 在集合中獲取所有電影
movies = collection.getElementsByTagName("movie")
# 打印每部電影的詳細信息
for movie in movies:
print "*****Movie*****"
if movie.hasAttribute("title"):
print "Title: %s" % movie.getAttribute("title")
type = movie.getElementsByTagName('type')[0]
print "Type: %s" % type.childNodes[0].data
format = movie.getElementsByTagName('format')[0]
print "Format: %s" % format.childNodes[0].data
rating = movie.getElementsByTagName('rating')[0]
print "Rating: %s" % rating.childNodes[0].data
description = movie.getElementsByTagName('description')[0]
print "Description: %s" % description.childNodes[0].data
```
以上程序執行結果如下:
```
Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Rating: PG
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Rating: R
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Description: Viewable boredom
```
完整的 DOM API 文檔請查閱[Python DOM APIs](//docs.python.org/library/xml.dom.html)。
# python GUI編程(Tkinter)
python提供了多個圖形開發界面的庫,幾個常用Python GUI庫如下:
* **Tkinter:** Tkinter模塊("Tk 接口")是Python的標準Tk GUI工具包的接口.Tk和Tkinter可以在大多數的Unix平臺下使用,同樣可以應用在Windows和Macintosh系統里.,Tk8.0的后續版本可以實現本地窗口風格,并良好地運行在絕大多數平臺中。
* **wxPython:**wxPython 是一款開源軟件,是 Python 語言的一套優秀的 GUI 圖形庫,允許 Python 程序員很方便的創建完整的、功能鍵全的 GUI 用戶界面。
* **Jython:**Jython程序可以和Java無縫集成。除了一些標準模塊,Jython使用Java的模塊。Jython幾乎擁有標準的Python中不依賴于C語言的全部模塊。比如,Jython的用戶界面將使用Swing,AWT或者SWT。Jython可以被動態或靜態地編譯成Java字節碼。
## Tkinter 編程
Tkinter 是Python的標準GUI庫。Python使用Tkinter可以快速的創建GUI應用程序。
由于Tkinter是內置到python的安裝包中、只要安裝好Python之后就能import Tkinter庫、而且IDLE也是用Tkinter編寫而成、對于簡單的圖形界面Tkinter還是能應付自如。
創建一個GUI程序
* 1、導入Tkinter模塊
* 2、創建控件
* 3、指定這個控件的master, 即這個控件屬于哪一個
* 4、告訴GM(geometry manager)有一個控件產生了。
實例:
```
#!/usr/bin/python
import Tkinter
top = Tkinter.Tk()
# 進入消息循環
top.mainloop()
```
以上代碼執行結果如下圖:

## Tkinter 組件
Tkinter的提供各種控件,如按鈕,標簽和文本框,一個GUI應用程序中使用。這些控件通常被稱為控件或者部件。
目前有15種Tkinter的部件。我們提出這些部件以及一個簡短的介紹,在下面的表:
| 控件 | 描述 |
| --- | --- |
| Button | 按鈕控件;在程序中顯示按鈕。 |
| Canvas | 畫布控件;顯示圖形元素如線條或文本 |
| Checkbutton | 多選框控件;用于在程序中提供多項選擇框 |
| Entry | 輸入控件;用于顯示簡單的文本內容 |
| Frame | 框架控件;在屏幕上顯示一個矩形區域,多用來作為容器 |
| Label | 標簽控件;可以顯示文本和位圖 |
| Listbox | 列表框控件;在Listbox窗口小部件是用來顯示一個字符串列表給用戶 |
| Menubutton | 菜單按鈕控件,由于顯示菜單項。 |
| Menu | 菜單控件;顯示菜單欄,下拉菜單和彈出菜單 |
| Message | 消息控件;用來顯示多行文本,與label比較類似 |
| Radiobutton | 單選按鈕控件;顯示一個單選的按鈕狀態 |
| Scale | 范圍控件;顯示一個數值刻度,為輸出限定范圍的數字區間 |
| Scrollbar | 滾動條控件,當內容超過可視化區域時使用,如列表框。. |
| Text | 文本控件;用于顯示多行文本 |
| Toplevel | 容器控件;用來提供一個單獨的對話框,和Frame比較類似 |
| Spinbox | 輸入控件;與Entry類似,但是可以指定輸入范圍值 |
| PanedWindow | PanedWindow是一個窗口布局管理的插件,可以包含一個或者多個子控件。 |
| LabelFrame | labelframe 是一個簡單的容器控件。常用與復雜的窗口布局。 |
| tkMessageBox | 用于顯示你應用程序的消息框。 |
## 標準屬性
標準屬性也就是所有控件的共同屬性,如大小,字體和顏色等等。
| 屬性 | 描述 |
| --- | --- |
| Dimension | 控件大小; |
| Color | 控件顏色; |
| Font | 控件字體; |
| Anchor | 錨點; |
| Relief | 控件樣式; |
| Bitmap | 位圖; |
| Cursor | 光標; |
## 幾何管理
Tkinter控件有特定的幾何狀態管理方法,管理整個控件區域組織,一下是Tkinter公開的幾何管理類:包、網格、位置
| 幾何方法 | 描述 |
| --- | --- |
| pack() | 包裝; |
| grid() | 網格; |
| place() | 位置; |
- Python 基礎教程
- Python 簡介
- Python 環境搭建
- Python 基礎語法
- Python 變量類型
- Python 運算符
- Python 條件語句
- Python 循環語句
- Python While循環語句
- Python for 循環語句
- Python 循環嵌套
- Python break 語句
- Python continue 語句
- Python pass 語句
- Python 數字
- Python 字符串
- Python 列表(Lists)
- Python 元組
- Python 字典(Dictionary)
- Python 日期和時間
- Python 函數
- Python 模塊
- Python 文件I/O
- Python 異常處理
- Python 高級教程
- Python 面向對象
- Python 正則表達式
- Python CGI編程
- Python 使用SMTP發送郵件
- Python 多線程
- Python 2.x與3??.x版本區別
- Python IDE
- Python JSON
- Python3 教程
- Python3 基礎語法
- Python3 基本數據類型
- Python3 解釋器
- Python3 注釋
- Python3 數字運算
- Python3 字符串
- Python3 列表
- Python3 編程第一步
- Python3 條件控制
- Python3 循環
- Python3 函數
- Python3 數據結構
- Python3 模塊
- Python3 輸入和輸出
- Python3 錯誤和異常
- Python3 類
- Python3 標準庫概覽
- 免責聲明