4.9 xml模塊node
xml是實現不一樣語言或程序之間進行數據交換的協議,跟json差很少,但json使用起來更簡單,不過,古時候,在json還沒誕生的混沌年代,你們只能選擇用xml,至今不少傳統公司如金融行業的不少系統的接口還主要是xml。python
xml的格式以下,就是經過<>節點來區別數據結構的:git
<?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data>
xml協議在各個語言裏的都 是支持的,在python中能夠用如下模塊操做xml算法
import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() print(root.tag) #遍歷xml文檔 for child in root: print(child.tag, child.attrib) for i in child: print(i.tag,i.text) #只遍歷year 節點 for node in root.iter('year'): print(node.tag,node.text)
修改和刪除xml文檔內容shell
import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() #修改 for node in root.iter('year'): new_year = int(node.text) + 1 node.text = str(new_year) node.set("updated","yes") tree.write("xmltest.xml")
#刪除node
for country in root.findall('country'):
rank = int(country.find('rank').text)
if rank > 50:
root.remove(country)
tree.write('output.xml')
本身建立xml文檔數據庫
import xml.etree.ElementTree as ET new_xml = ET.Element("namelist") name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) age = ET.SubElement(name,"age",attrib={"checked":"no"}) sex = ET.SubElement(name,"sex") sex.text = '33' name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"}) age = ET.SubElement(name2,"age") age.text = '19' et = ET.ElementTree(new_xml) #生成文檔對象 et.write("test.xml", encoding="utf-8",xml_declaration=True) ET.dump(new_xml) #打印生成的格式
4.10 configparser模塊json
此模塊用於生成和修改常見配置文檔,當前模塊的名稱在 python 3.x 版本中變動爲 configparser。緩存
看一個好多軟件的常見配置文件格式以下安全
```cnf [DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [bitbucket.org] User = hg [topsecret.server.com] Port = 50022 ForwardX11 = no ```
解析配置文件數據結構
```py >>> import configparser # 導入模塊 >>> config = configparser.ConfigParser() #實例化(生成對象) >>> config.sections() #調用sections方法 [] >>> config.read('example.ini') # 讀配置文件(注意文件路徑) ['example.ini'] >>> config.sections() #調用sections方法(默認不會讀取default) ['bitbucket.org', 'topsecret.server.com'] >>> 'bitbucket.org' in config #判斷元素是否在sections列表內 True >>> 'bytebong.com' in config False >>> config['bitbucket.org']['User'] # 經過字典的形式取值 'hg' >>> config['DEFAULT']['Compression'] 'yes' >>> topsecret = config['topsecret.server.com'] >>> topsecret['ForwardX11'] 'no' >>> topsecret['Port'] '50022' >>> for key in config['bitbucket.org']: print(key) # for循環 bitbucket.org 字典的key ... user compressionlevel serveraliveinterval compression forwardx11 >>> config['bitbucket.org']['ForwardX11'] 'yes' ```
其它增刪改查語法
```python [group1] # 支持的兩種分隔符「=」, 「:」 k1 = v1 k2:v2 [group2] k1 = v1 import ConfigParser config = ConfigParser.ConfigParser() config.read('i.cfg') # ########## 讀 ########## #secs = config.sections() #print(secs) #options = config.options('group2') # 獲取指定section的keys #print(options) #item_list = config.items('group2') # 獲取指定 section 的 keys & values ,key value 以元組的形式 #print(item_list) #val = config.get('group1','key') # 獲取指定的key 的value #val = config.getint('group1','key') # ########## 改寫 ########## #sec = config.remove_section('group1') # 刪除section 並返回狀態(true, false) #config.write(open('i.cfg', "w")) # 對應的刪除操做要寫入文件纔會生效 #sec = config.has_section('wupeiqi') #sec = config.add_section('wupeiqi') #config.write(open('i.cfg', "w")) # #config.set('group2','k1',11111) #config.write(open('i.cfg', "w")) #config.remove_option('group2','age') #config.write(open('i.cfg', "w")) ```
4.11 hashlib模塊
Hash,通常翻譯作「散列」,也有直接音譯爲」哈希」的,就是把任意長度的輸入(又叫作預映射,pre-image),經過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間一般遠小於輸入的空間,不一樣的輸入可能會散列成相同的輸出,而不可能從散列值來惟一的肯定輸入值。
簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。
HASH主要用於信息安全領域中加密算法,他把一些不一樣長度的信息轉化成雜亂的128位的編碼裏,叫作HASH值.也能夠說,hash就是找到一種數據內容和數據存放地址之間的映射關係
什麼是MD5算法
MD5訊息摘要演算法(英語:MD5 Message-Digest Algorithm),一種被普遍使用的密碼雜湊函數,能夠產生出一個128位的散列值(hash value),用於確保信息傳輸完整一致。MD5的前身有MD二、MD3和MD4。
MD5功能
輸入任意長度的信息,通過處理,輸出爲128位的信息(數字指紋);
不一樣的輸入獲得的不一樣的結果(惟一性);
MD5算法的特色
MD5算法是否可逆?
MD5不可逆的緣由是其是一種散列函數,使用的是hash算法,在計算過程當中原文的部分信息是丟失了的。
MD5用途
防止被篡改:
好比發送一個電子文檔,發送前,我先獲得MD5的輸出結果a。而後在對方收到電子文檔後,對方也獲得一個MD5的輸出結果b。若是a與b同樣就表明中途未被篡改。
好比我提供文件下載,爲了防止不法分子在安裝程序中添加木馬,我能夠在網站上公佈由安裝文件獲得的MD5輸出結果。
SVN在檢測文件是否在CheckOut後被修改過,也是用到了MD5.
防止直接看到明文:
防止抵賴(數字簽名):
SHA-1
安全哈希算法(Secure Hash Algorithm)主要適用於數字簽名標準(Digital Signature Standard DSS)裏面定義的數字簽名算法(Digital Signature Algorithm DSA)。對於長度小於2^64位的消息,SHA1會產生一個160位的消息摘要。當接收到消息的時候,這個消息摘要能夠用來驗證數據的完整性。
SHA是美國國家安全局設計的,由美國國家標準和技術研究院發佈的一系列密碼散列函數。
因爲MD5和SHA-1於2005年被山東大學的教授王小云破解了,科學家們又推出了SHA224, SHA256, SHA384, SHA512,固然位數越長,破解難度越大,但同時生成加密的消息摘要所耗時間也更長。目前最流行的是加密算法是SHA-256 .
因爲MD5與SHA-1均是從MD4發展而來,它們的結構和強度等特性有不少類似之處,SHA-1與MD5的最大區別在於其摘要比MD5摘要長32 比特。對於強行攻擊,產生任何一個報文使之摘要等於給定報文摘要的難度:MD5是2128數量級的操做,SHA-1是2160數量級的操做。產生具備相同摘要的兩個報文的難度:MD5是264是數量級的操做,SHA-1 是280數量級的操做。於是,SHA-1對強行攻擊的強度更大。但因爲SHA-1的循環步驟比MD5多80:64且要處理的緩存大160比特:128比特,SHA-1的運行速度比MD5慢。
Python的提供的相關模塊
用於加密相關的操做,3.x裏代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib m = hashlib.md5() m.update(b"Hello") m.update(b"It's me") print(m.digest()) m.update(b"It's been a long time since last time we ...") print(m.digest()) #2進制格式hash print(len(m.hexdigest())) #16進制格式hash ''' def digest(self, *args, **kwargs): # real signature unknown """ Return the digest value as a string of binary data. """ pass def hexdigest(self, *args, **kwargs): # real signature unknown """ Return the digest value as a string of hexadecimal digits. """ pass ''' import hashlib # ######## md5 ######## hash = hashlib.md5() hash.update('admin') print(hash.hexdigest()) # ######## sha1 ######## hash = hashlib.sha1() hash.update('admin') print(hash.hexdigest()) # ######## sha256 ######## hash = hashlib.sha256() hash.update('admin') print(hash.hexdigest()) # ######## sha384 ######## hash = hashlib.sha384() hash.update('admin') print(hash.hexdigest()) # ######## sha512 ######## hash = hashlib.sha512() hash.update('admin') print(hash.hexdigest())
4.12 subprocess模塊
咱們常常須要經過Python去執行一條系統命令或腳本,系統的shell命令是獨立於你的python進程以外的,每執行一條命令,就是發起一個新進程,經過python調用系統命令或腳本的模塊在python2有os.system,如:
>>> os.system('uname -a') Darwin Alexs-MacBook-Pro.local 15.6.0 Darwin Kernel Version 15.6.0: Sun Jun 4 21:43:07 PDT 2017; root:xnu-3248.70.3~1/RELEASE_X86_64 x86_64 0
這條命令的實現原理是什麼呢?(視頻中講,解釋進程間通訊的問題...)
除了os.system能夠調用系統命令,,commands,popen2等也能夠,比較亂,因而官方推出了subprocess,目地是提供統一的模塊來實現對系統命令或腳本的調用
The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to replace several older modules and functions:
The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases, the underlying Popen interface can be used directly.
The run() function was added in Python 3.5; if you need to retain compatibility with older versions, see the Older high-level API section.
三種執行命令的方法
subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs) #官方推薦
subprocess.call(*popenargs, timeout=None, **kwargs) #跟上面實現的內容差很少,另外一種寫法
subprocess.Popen() #上面各類方法的底層封裝
Run command with arguments and return a CompletedProcess instance.The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.
If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured.
If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised.
The other arguments are the same as for the Popen constructor.
標準寫法
subprocess.run(['df','-h'],stderr=subprocess.PIPE,stdout=subprocess.PIPE,check=True
涉及到管道|的命令須要這樣寫
subprocess.run('df -h|grep disk1',shell=True) #shell=True的意思是這條命令直接交給系統去執行,不須要python負責解析
call()方法
#執行命令,返回命令執行狀態 , 0 or 非0 >>> retcode = subprocess.call(["ls", "-l"]) #執行命令,若是命令結果爲0,就正常返回,不然拋異常 >>> subprocess.check_call(["ls", "-l"]) 0 #接收字符串格式命令,返回元組形式,第1個元素是執行狀態,第2個是命令結果 >>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') #接收字符串格式命令,並返回結果 >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' #執行命令,並返回結果,注意是返回結果,不是打印,下例結果返回給res >>> res=subprocess.check_output(['ls','-l']) >>> res b'total 0\ndrwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM\n'
經常使用參數:
下面這2條語句執行會有什麼區別?
a=subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE) a=subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)
區別是Popen會在發起命令後馬上返回,而不等命令執行結果。這樣的好處是什麼呢?
若是你調用的命令或腳本 須要執行10分鐘,你的主程序不需卡在這裏等10分鐘,能夠繼續往下走,幹別的事情,每過一會,經過一個什麼方法來檢測一下命令是否執行完成就行了。
Popen調用後會返回一個對象,能夠經過這個對象拿到命令執行結果或狀態等,該對象有如下方法
poll()
Check if child process has terminated. Returns returncode
wait()
Wait for child process to terminate. Returns returncode attribute.
terminate()
終止所啓動的進程Terminate the process with SIGTERM
kill()
殺死所啓動的進程 Kill the process with SIGKILL
communicate()
與啓動的進程交互,發送數據到stdin,並從stdout接收輸出,而後等待任務結束
>>> a = subprocess.Popen('python3 guess_age.py',stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,shell=True) >>> a.communicate(b'22') (b'your guess:try bigger\n', b'')
send_signal(signal.xxx)
發送系統信號
pid
拿到所啓動進程的進程號