1. 程式人生 > 實用技巧 >Python學習筆記(4)

Python學習筆記(4)

Python 解析 XML檔案

python 中使用 xml.dom.minidom模組來解析XML檔案, xml.dom.minidom.parse() 用於開啟一個XML檔案,並將這個檔案物件轉為xmldom變數。

xmldom.documentElement 用於得到dom物件的根節點,並把獲得的物件給root ,每一個節點都有它的 nodeName 、 nodeValue 、 nodeType 屬性, nodeName 為節點名字, nodeValue 是節點的值(只對文字節點有效), nodeType 是節點的型別, nodeType 的12種類型:

#encoding = utf-8
import xml.dom.minidom

# 開啟一個XML檔案
xmlcode = xml.dom.minidom.parse('dome.xml')
print(xmlcode)
# 獲取XML檔案的根節點
root = xmlcode.documentElement
# 獲取節點的名字
print(root.nodeName)
print(root.nodeValue)
print(root.nodeType)
# 獲得節點下的所有子節點  包括換行節點
print(root.childNodes)
# 獲得根節點下的 stydent 子節點
stunodes = root.getElementsByTagName('student')
print(stunodes)
for n in stunodes:
  if stunodes.getAttribute('id') == 1:
    # 修改節點內容
    n.getElementsByTagName('name')[0].firstChild.data = '新內容'
    break
# 判斷屬性是否存在
print(root.hasAttribute('id'))
# 獲取屬性
print(root.getAttribute('id'))
# 設定屬性
root.setAttribute('id', 12)
# 建立一個新的節點 並新增到根節點下
newElemt = xmlcode.createElement('new')
newElemt.setAttribute('id', 13)
root.appendChild(newElemt)
# 把更改後的DOM物件寫入檔案
xmlFile = open('dome.xml', mode="w", encoding="utf-8")
xmlFile.write(xmlcode.toprettyxml())

在python 中使用 SAX 解析 XML

SAX是一種基於事件驅動的API , 通常包含三個事件: 開始解析標籤事件、解析資料事件、結束解析標籤事件

利用 SAX 解析 XML 文件涉及兩個部分:解析器和事件處理器。解析器負責讀取XML文件,並向事件處理器傳送事件,如元素開始和元素結束事件。而事件處理器則負責對事件作出相應資料進行處理。

SAX解析XML適用場景: 1、對大型檔案進行處理; 2、只需要檔案的部分內容,或者只需從檔案中得到特定資訊。

#encoding=utf-8

#匯入相關模組
import xml.sax
import xml.sax.handler

# 定義一個類,並繼承 xml.sax.ContentHandler
class studentHander(xml.sax.ContentHandler):
  def __init__ (self):
    print('開始解析')

  #開始解析文件
  def startDocument(self):
    print('開始解析文件')

  #結束文件解析
  def endDocument(self):
    print('結束文件解析')

  # 開始解析某個標籤
  def startElement(self, name, attrs):
    print('{0}標籤開始解析'.format(name))
    if name == 'movie':
      print('該標籤的屬性值為{0}'.format(attrs['title']))

  # 結束解析某個標籤
  def endElement(self, name):
    print('{0}標籤結束解析'.format(name))

  # 解析過程,獲得解析得到的值
  def characters(self, content):
    print('解析過程,獲得解析得到的值為{0}'.format(content))

# 建立一個新的解析器物件並返回
parser = xml.sax.make_parser()

# 指定解析器的ContentHandler物件
parser.setContentHandler(studentHander())

# 解析XML檔案
parser.parse("dome.xml")

多執行緒

執行中的程式,稱為程序;一個程式對應一個程序,一個程序可包含多個執行緒。

執行緒,有時被稱為輕量級程序,是程式執行流的最小單位。一個執行緒可以建立和撤銷另一個執行緒,同一個程序中的多個執行緒之間可以併發執行。

執行緒有就緒、阻塞、執行三種基本狀態。

python 通過兩個標準庫 _thread 和 threading 提供對執行緒的支援。_thread 提供了低級別的、原始的執行緒以及一個簡單的鎖。相對於 threading 模組功能有限。

threading 模組包含了 _thread模組所有的方法,還提供其他的方法:

threading.currentThread() : 返回當前的執行緒變數

threading.enumerate(): 返回一個包含正在執行的執行緒的list 。正在執行指執行緒啟動後、結束前。不包括啟動前和終止後的執行緒。

threading.activeCount() : 返回正在執行的執行緒數量,相對於 len(threading.enumerate())

除了threading模組的方法外,執行緒模組同樣提供了 Thread 類來處理執行緒, Thread 類提供了以下方法:

run() : 用來表示執行緒活動

start() : 啟動執行緒活動

join([time]): 等待至執行緒終止,這阻塞呼叫執行緒直至執行緒的join() 方法被呼叫終止,正常退出或者丟擲未處理的異常或者是可選的超時發生

isAlive() : 返回執行緒是否活動

getName() : 返回執行緒名

setName() : 設定執行緒名

#encoding=utf-8
import threading
# 獲得當前的執行緒物件
currentThread = threading.currentThread()
# 執行緒是否正在執行
print(currentThread.isAlive())
# 執行緒名字
print(currentThread.getName())
# 是否為後臺執行緒
print(currentThread.isDaemon())
# 正在執行的執行緒數量
print(threading.activeCount())
# 正在執行的所有執行緒列表
print(threading.enumerate())

使用函式建立多執行緒:

#encoding=utf-8
import time
import _thread
def showTime(name, delayTime):
  count = 1
  while count <=6:
    time.sleep(delayTime)
    count = count + 1
    print('執行體的名字{0},當前時間{1}'.format(name, time.ctime(time.time())))

# 依次執行各個方法,需要耗費長時間
# showTime('cs1', 2)
# showTime('cs2', 2)
# showTime('cs3', 2)
# showTime('cs4', 2)

# 使用函式建立多執行緒
try:
  # 開啟設定多個執行緒
  _thread.start_new_thread(showTime, ('cs1', 2))
  _thread.start_new_thread(showTime, ('cs2', 2))
  _thread.start_new_thread(showTime, ('cs3', 2))
  _thread.start_new_thread(showTime, ('cs4', 2))
  print('設定完畢')
except:
  print('error')
finally:
  while True:
    pass

使用類來建立多執行緒:

#encoding=utf-8
import time
import threading
def showTime(name, delayTime):
  count = 1
  while count <=6:
    time.sleep(delayTime)
    count = count + 1
    print('執行體的名字{0},當前時間{1}'.format(name, time.ctime(time.time())))

# 依次執行各個方法,需要耗費長時間
# showTime('cs1', 2)
# showTime('cs2', 2)
# showTime('cs3', 2)
# showTime('cs4', 2)

# 使用類來建立多執行緒
class myThread(threading.Thread):
  def __init__(self, name, delayTime):
    threading.Thread.__init__(self)    # 重點
    self.name = name
    self.delayTime = delayTime
  
  # 定義多執行緒執行邏輯,通過 start方法觸發
  def run(self):
    print('{0}多執行緒開始執行'.format(self.name))
    showTime(self.name, self.delayTime)

myThread1 = myThread('cs1', 2)
myThread2 = myThread('cs2', 2)
myThread3 = myThread('cs3', 2)
myThread4 = myThread('cs4', 2)

myThread1.start()   # 呼叫 start 方法, 會自動呼叫類裡面的 run 方法
myThread2.start()
myThread3.start()
myThread4.start()

多執行緒的同步:

#encoding=utf-8
import threading
import time

count = 2
# 獲得 lock物件,鎖,用於多執行緒的同步
lock = threading.Lock()

class saleTick(threading.Thread):
  def __init__(self, name):
    threading.Thread.__init__(self)
    self.name = name

  def run(self):
    global count, lock
    # 進行鎖定,此時其他執行緒該部分進入阻塞狀態,會等該部分解鎖後繼續執行,用於保持資料的同步
    lock.acquire()
    if count >= 1:
      time.sleep(2)
      count = count - 1
      print('買到票,餘票{0}'.format(count))
    else:
      print('沒搶到票')
    # 進行解鎖,其他執行緒可使用
    lock.release()



thread1 = saleTick('p1')
thread2 = saleTick('p2')
thread3 = saleTick('p3')
thread4 = saleTick('p4')

thread1.start()
thread2.start()
thread3.start()
thread4.start()

裝飾器

裝飾器是把一個函式作為引數的函式,常常用於擴充套件已有函式,即不改變當前函式狀態下增加功能。 通常使用 @名稱 標記

import time

# 定義一個裝飾器
def countTime(f):
  def wrapper(*args, **kwargs):   # 傳入引數,表示可有可無
    begin = time.time()
    f(*args, **kwargs)      # 這裡代表的是使用裝飾器的函式邏輯
    end = time.time()
    print(end - begin)
  return wrapper

@countTime
def test():
  for n in range(100):
    for t in range(100):
      pass


test()

單例模式

一個類自始至終只產生一個例項物件,稱為單例模式。

單例模式三個要點:1、某個類只能有一個例項 ; 2、 它必須自行建立這個例項; 3、它必須自行向整個系統提供這個例項;

#encoding=utf-8

# 建立單例模式類
class Singleton(object):      # object 是所有類的父類
  # 定義一個變數儲存例項物件
  _singletObject = None
  # 構造方法
  def __init__(self, *args, **kwargs):
    object.__init__(self, *args, **kwargs)
  # 初始化方法
  def __new__(cls, *args, **kwargs):
    if Singleton._singletObject is None:     # 如果當前沒有例項物件
      Singleton._singletObject = object.__new__(cls)    #建立一個例項物件並存儲
    return Singleton._singletObject               # 存在例項物件,直接將其返回
      

# 建立一個類,繼承單例模式
class Myclass(Singleton):
  def __init__(self, name):
    Singleton.__init__(self)   # 呼叫父類的構造方法
    self.name = name

# 這裡建立的都是同個例項物件
a = Myclass('a')
b= Myclass('b')

print(a.name)    # b
print(b.name)    # b