python學習筆記之常用模塊(第五天)


 

  參考老師的博客:

       金角:http://www.cnblogs.com/alex3714/articles/5161349.html

       銀角:http://www.cnblogs.com/wupeiqi/articles/4963027.html

 

一、常用函數說明:

 ★ lamba

python lambda是在python中使用lambda來創建匿名函數,而用def創建的方法是有名稱的,除了從表面上的方法名不一樣外,python lambda還有哪些和def不一樣呢?

1 python lambda會創建一個函數對象,但不會把這個函數對象賦給一個標識符,而def則會把函數對象賦值給一個變量。
2 python lambda它只是一個表達式,而def則是一個語句。

 

lambda語句中,冒號前是參數,可以有多個,用逗號隔開,冒號右邊的返回值。lambda語句構建的其實是一個函數對象。

例:

m = lambda x,y,z: (x-y)*z
print m(234,122,5)

 

也經常用於生成列表,例:


list = [i ** i for i in range(10)]
print(list)

list_lambda = map(lambda x:x**x,range(10))
print(list_lambda)


 

 ★ enumerate(iterable,[start])   iterable為一個可迭代的對象;

enumerate(iterable[, start]) -> iterator for index, value of iterable Return an enumerate object.  iterable must be another object  that supports iteration.  The enumerate object yields pairs containing a count  (from start, which defaults to zero) and a value yielded by the iterable 
 argument. enumerate is useful for obtaining an indexed list:    (0, seq[0]), (1, seq[1]), (2, seq[2]), ...

例:


for k,v in enumerate(['a','b','c',1,2,3],10):
        print k,v 


 

★S.format(*args, **kwargs) -> string  字符串的格式輸出,類似於格式化輸出%s

        Return a formatted version of S, using substitutions from args and kwargs.
        The substitutions are identified by braces ('{' and '}').

s = 'i am {0},{1}'
print(s.format('wang',1))

 

★map(function,sequence) 將squence每一項做為參數傳給函數,並返回值

例:


def add(arg):
    return arg + 101
print(map(add,[12,23,34,56]))


 

★filter(function or None, sequence) -> list, tuple, or string  返還true的序列
        Return those items of sequence for which function(item) is true.  If
    function is None, return the items that are true.  If sequence is a tuple
    or string, return the same type, else return a list.

例:


def comp(arg):
    if arg < 8:
        return True
    else:
        return False  
print(filter(comp,[1,19,21,8,5]))
print(filter(lambda x:x % 2,[1,19,20,8,5]))
print(filter(lambda x:x % 2,(1,19,20,8,5)))
print(filter(lambda x:x > 'a','AbcdE'))


 注:因為在3.3里面,map(),filter()這些的返回值已經不再是list,而是iterators, 所以想要使用,只用將iterator 轉換成list 即可, 比如 list(map()) 

★reduce(function, sequence[, initial]) -> value   對二個參數進行計算
Apply a function of two arguments cumulatively to the items of a  sequence,
from left to right, so as to reduce the sequence to a single value.For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates((((1+2)+3)+4)+5).  If initial is present, it is placed before the 
 items of the sequence in the calculation, and serves as a default when  the sequence is empty.

例:


print(reduce(lambda x,y:x*y,[22,11,8]))
print(reduce(lambda x,y:x*y,[3],10))

print(reduce(lambda x,y:x*y,[],5))


 

★zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)] 將多個序列轉化為新元祖的序列
Return a list of tuples, where each tuple contains the i-th element from each of the argument sequences.  The returned list is  truncated in length to the length of the shortest argument sequence.

例:


a = [1,2,3,4,5,6]
b = [11,22,33,44,55]
c = [111,222,333,444]
print(zip(a,b,c))


 

★eval(source[, globals[, locals]]) -> value 將表達式字符串執行為值,其中globals為全局命名空間,locals為局部命名空間,從指字的命名空間中執行表達式,
        Evaluate the source in the context of globals and locals.    The source may be a string representing a Python expression  or a code object as returned by compile().    The globals must be a dictionary and locals can be any mapping,    defaulting to the current globals and locals.    If only globals is given, locals defaults to it.

例:


a = '8*(8+20-5%12*23'
print(eval(a))

d = {'a':5,'b':4}
print(eval('a*b',d))


 

★exec(source[, globals[, locals]]) 語句用來執行儲存在字符串或文件中的Python語句

例:


a = 'print("nihao")'

b = 'for i in range(10): print i'

exec(a) 

exec(b)


 

★execfile(filename[, globals[, locals]])
     Read and execute a Python script from a file.The globals and locals are dictionaries, defaulting to the currentglobals and locals.  If only globals is given, locals defaults to it.

 

二、模塊 paramiko

paramiko是一個用於做遠程控制的模塊,使用該模塊可以對遠程服務器進行命令或文件操作,值得一說的是,fabric和ansible內部的遠程管理就是使用的paramiko來現實。

1、下載安裝(pycrypto,由於 paramiko 模塊內部依賴pycrypto,所以先下載安裝pycrypto)

2、使用模塊

#!/usr/bin/env python
#coding:utf-8

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.1.108', 22, 'alex', '123')
stdin, stdout, stderr = ssh.exec_command('df')
print stdout.read()
ssh.close();
通過用戶名和密碼連接服務器
import paramiko

private_key_path = '/home/auto/.ssh/id_rsa'
key = paramiko.RSAKey.from_private_key_file(private_key_path)

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('主機名 ', 端口, '用戶名', key)

stdin, stdout, stderr = ssh.exec_command('df')
print stdout.read()
ssh.close()
過密鑰鏈接服務器
import os,sys
import paramiko

t = paramiko.Transport(('182.92.219.86',22))
t.connect(username='wupeiqi',password='123')
sftp = paramiko.SFTPClient.from_transport(t)
sftp.put('/tmp/test.py','/tmp/test.py') 
t.close()


import os,sys
import paramiko

t = paramiko.Transport(('182.92.219.86',22))
t.connect(username='wupeiqi',password='123')
sftp = paramiko.SFTPClient.from_transport(t)
sftp.get('/tmp/test.py','/tmp/test2.py')
t.close()
上傳或者下載文件 - 通過用戶名和密碼
import paramiko

pravie_key_path = '/home/auto/.ssh/id_rsa'
key = paramiko.RSAKey.from_private_key_file(pravie_key_path)

t = paramiko.Transport(('182.92.219.86',22))
t.connect(username='wupeiqi',pkey=key)

sftp = paramiko.SFTPClient.from_transport(t)
sftp.put('/tmp/test3.py','/tmp/test3.py') 

t.close()

import paramiko

pravie_key_path = '/home/auto/.ssh/id_rsa'
key = paramiko.RSAKey.from_private_key_file(pravie_key_path)

t = paramiko.Transport(('182.92.219.86',22))
t.connect(username='wupeiqi',pkey=key)

sftp = paramiko.SFTPClient.from_transport(t)
sftp.get('/tmp/test3.py','/tmp/test4.py') 

t.close()
上傳或下載文件 - 通過密鑰

 

三、其他常用模塊:

1、random模塊:

★random 生成隨機數

print random.random()             生成0-1之間的小數

print random.randint(1,3)         生成整數,包含endpoint

print random.randrange(1,3,2)    生成整數,不包含endpoint

randrange(self, start, stop=None, step=?)

生成5位隨機數,例:


import random

a = []
for i in range(5):
    if i == random.randint(1,5):
        a.append(str(i))
    else:
        a.append(chr(random.randint(65,90)))
else:        
    print(''.join(a))

 

2、MD5、sha、hashlib模塊

★生成MD5碼

例:


一. 使用md5包

import md5
src = 'this is a md5 test.'   
m1 = md5.new()   
m1.update(src)   
print m1.hexdigest()

二、使用sha包

import sha

hash = sha.new()

hash.update('admin')

print hash.hexdigest()

三. 使用hashlib

用於加密相關的操作,代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

錯誤:“Unicode-objects must be encoded before hashing”,意思是在進行md5哈希運算前,需要對數據進行編碼,使用encode("utf8")

import hashlib
hash = hashlib.md5()
hash.update('this is a md5 test.'.encode("utf8")

hash.update('admin')

print(hash.digest())

print(hash.hexdigest())

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()
hashlib

推薦使用第三種方法。

 

對以上代碼的說明:

1.首先從python直接導入hashlib模塊

2.調用hashlib里的md5()生成一個md5 hash對象

3.生成hash對象后,就可以用update方法對字符串進行md5加密的更新處理

4.繼續調用update方法會在前面加密的基礎上更新加密

5.加密后的二進制結果

6.十六進制結果

如果只需對一條字符串進行加密處理,也可以用一條語句的方式:

print(hashlib.new("md5", "Nobody inspects the spammish repetition").hexdigest())


 

以上加密算法雖然依然非常厲害,但時候存在缺陷,即:通過撞庫可以反解。所以,有必要對加密算法中添加自定義key再來做加密

1
2
3
4
5
6
7
import  hashlib
 
# ######## md5 ########
 
hash  =  hashlib.md5( '898oaFs09f' )
hash .update( 'admin' )
print  hash .hexdigest()

還不夠吊?python 還有一個 hmac 模塊,它內部對我們創建 key 和 內容 再進行處理然后再加密

1
2
3
4
import  hmac
=  hmac.new( 'wueiqi' )
h.update( 'hellowo' )
print  h.hexdigest()

不能再牛逼了!!!

 

3、pickle和json模塊:

python對象與文件之間的序列化和反序列化(pickle和json)

用於序列化的兩個模塊

  • json,用於字符串 和 python數據類型間進行轉換
  • pickle,用於python特有的類型 和 python的數據類型間進行轉換

Json模塊提供了四個功能:dumps、dump、loads、load

pickle模塊提供了四個功能:dumps、dump、loads、load

 

pickle模塊用來實現python對象的序列化和反序列化。通常地pickle將python對象序列化為二進制流或文件。

 python對象與文件之間的序列化和反序列化:

pickle.dump()

pickle.load()

如果要實現python對象和字符串間的序列化和反序列化,則使用:

pickle.dumps()

pickle.loads()

 

可以被序列化的類型有:

* None,True 和 False;

* 整數,浮點數,復數;

* 字符串,字節流,字節數組;

* 包含可pickle對象的tuples,lists,sets和dictionaries;

* 定義在module頂層的函數:

* 定義在module頂層的內置函數;

* 定義在module頂層的類;

* 擁有__dict__()或__setstate__()的自定義類型;

注意:對於函數或類的序列化是以名字來識別的,所以需要import相應的module。

例:


 1 import pickle
 2 
 3 class test():
 4     def __init__(self,n):
 5         self.a = n
 6 
 7 t = test(123)
 8 t2 = test('abc')
 9 
10 a_list = ['sky','mobi','mopo']
11 a_dict = {'a':1,'b':2,'3':'c'}
12 
13 with open('test.pickle','wb') as f:
14     pickle.dump(t,f)
15     pickle.dump(a_list,f)
16     pickle.dump(t2,f)
17 
18 with open('test.pickle','rb') as g:
19     gg = pickle.load(g)
20     print(gg.a)
21     hh = pickle.load(g)
22     print(hh[1])
23     ii = pickle.load(g)
24     print(ii.a)

注:dump和load一一對應,順序也不會亂。


 

★JSON(JavaScript Object Notation):一種輕量級數據交換格式,相對於XML而言更簡單,也易於閱讀和編寫,機器也方便解析和生成,Json是JavaScript中的一個子集。

        Python的Json模塊序列化與反序列化的過程分別是 encoding和 decoding

encoding:把一個Python對象編碼轉換成Json字符串
decoding:把Json格式字符串解碼轉換成Python對象

具體的轉化對照如下:

wKioL1VprBeD1xnRAACCe3LFXm0411.jpg

 

loads方法返回了原始的對象,但是仍然發生了一些數據類型的轉化。比如,上例中‘abc’轉化為了unicode類型。從json到python的類型轉化對照如下:

 

wKiom1VpqoKjQI2jAACEP9X7Um8733.jpg

例:


 1 import json
 2 
 3 data = {    'a': [1, 2.0, 3, 4],    'b': ("character string", "byte string"),    'c': 'abc'}
 4 
 5 du = json.dumps(data)
 6 print(du)
 7 print(json.loads(du,encoding='ASCII'))
 8 
 9 with open('data.json','w') as f:
10     json.dump(data,f,indent=2,sort_keys=True,separators=(',',':'))
#
f.write(json.dumps(data))
11
12 with open('data.json','r') as f:
13 data = json.load(f)
14 print(repr(data))

注:json並不像pickle一樣,將python對象序列化為二進制流或文件,所以寫或讀不能加b;

      同時只能針對一個對象或類型進行dump和load,不像pickle可以多個。

      sort_keys是告訴編碼器按照字典排序(a到z)輸出

      indent參數根據數據格式縮進顯示,讀起來更加清晰:

      separators參數的作用是去掉,,:后面的空格,從上面的輸出結果都能看到", :"后面都有個空格,這都是為了美化輸出結果的作用,但是在我們傳輸數據的過程中,越精簡越好,冗余的東西全部去掉


經測試,2.7版本導出的json文件,3.4版本導入會報錯:TypeError: the JSON object must be str, not 'bytes'

 

4、正則表達式模塊:

re模塊用於對python的正則表達式的操作。

字符:

  . 匹配除換行符以外的任意字符
  \w 匹配字母或數字或下划線或漢字
  \s 匹配任意的空白符
  \d 匹配數字
  \b 匹配單詞的開始或結束
  ^ 匹配字符串的開始
  $ 匹配字符串的結束

次數:

  * 重復零次或更多次
  + 重復一次或更多次
  ? 重復零次或一次
  {n} 重復n次
  {n,} 重復n次或更多次
  {n,m} 重復n到m次

IP:
^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$
手機號:
^1[3|4|5|8][0-9]\d{8}$

★re.match的函數原型為:re.match(pattern, string, flags)

第一個參數是正則表達式,這里為"(\w+)\s",如果匹配成功,則返回一個Match,否則返回一個None;

第二個參數表示要匹配的字符串;

第三個參數是標致位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。

 

★re.search的函數原型為: re.search(pattern, string, flags)

每個參數的含意與re.match一樣。 

re.match與re.search的區別:re.match只匹配字符串的開始,如果字符串開始不符合正則表達式,則匹配失敗,函數返回None;而re.search匹配整個字符串,直到找到一個匹配。

 

★re.findall可以獲取字符串中所有匹配的字符串。如:re.findall(r'\w*oo\w*', text);獲取字符串中,包含'oo'的所有單詞。

 

★re.sub的函數原型為:re.sub(pattern, repl, string, count)

其中第二個函數是替換后的字符串;本例中為'-'

第四個參數指替換個數。默認為0,表示每個匹配項都替換。

re.sub還允許使用函數對匹配項的替換進行復雜的處理。如:re.sub(r'\s', lambda m: '[' + m.group(0) + ']', text, 0);將字符串中的空格' '替換為'[ ]'。

 

★re.split可以使用re.split來分割字符串,如:re.split(r'\s+', text);將字符串按空格分割成一個單詞列表。

根據指定匹配進行分組

content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'"
new_content = re.split('\*', content)
# new_content = re.split('\*', content, 1)
print new_content
content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'"
new_content = re.split('[\+\-\*\/]+', content)
# new_content = re.split('\*', content, 1)
print new_content
inpp = '1-2*((60-30 +(-40-5)*(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))'
inpp = re.sub('\s*','',inpp)
new_content = re.split('\(([\+\-\*\/]?\d+[\+\-\*\/]?\d+){1}\)', inpp, 1)
print new_content

★re.compile可以把正則表達式編譯成一個正則表達式對象。可以把那些經常使用的正則表達式編譯成正則表達式對象,這樣可以提高一定的效率。下面是一個正則表達式對象的一個例子:

例:


import re

r = re.compile('\d+')
r1 = r.match('adfaf123asdf1asf1123aa')
if r1:
    print(r1.group())
else:
    print('no match')

r2 = r.search('adfaf123asdf1asf1123aa')
if r2:
    print(r2.group())
    print(r2.groups())
else:
    print('no match')
    
r3 = r.findall('adfaf123asdf1asf1123aa')
if r3:
    print(r3)
else:
    print('no match')
    
r4 = r.sub('###','adfaf123asdf1asf1123aa')
print(r4)

r5 = r.subn('###','adfaf123asdf1asf1123aa')
print(r5)

r6 = r.split('adfaf123asdf1asf1123aa',maxsplit=2)
print(r6)


注:re執行分二步:首先編譯,然后執行。故先使用re.compile進行查詢的字符串進行編譯,之后的操作無需在次編譯,可以提高效率。

匹配IP具體實例:

 


ip = '12aa13.12.15aasdfa12.32aasdf192.168.12.13asdfafasf12abadaf12.13'
res = re.findall('(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})',ip)
print(res)
res1 = re.findall('(?:\d{1,3}\.){3}\d{1,3}',ip)
print(res1)


 

     而group,groups 主要是針對查詢的字符串是否分組,一般只是針對search和match,即'\d+' 和('\d+') 輸出結果為:

123   和('123',)。

import re
a = 'Oldboy School,Beijing Changping shahe:010-8343245'

match = re.search(r'(\D+),(\D+):(\S+)',a)
print(match.group(1))
print(match.group(2))
print(match.group(3))

print("##########################")

match2 = re.search(r'(?P<name>\D+),(?P<address>\D+):(?P<phone>\S+)',a)
print(match2.group('name'))
print(match2.group('address'))
print(match2.group('phone'))

 

 

5、time模塊

time模塊提供各種操作時間的函數

#1、時間戳    1970年1月1日之后的秒
#2、元組 包含了:年、日、星期等... time.struct_time
#3、格式化的字符串    2014-11-11 11:11

wKioL1Vp-q-T-pkOAAD5WwIMSLo937.jpg

 


import time

import  datetime
 
print (time.clock())  #返回處理器時間,3.3開始已廢棄
print (time.process_time())  #返回處理器時間,3.3開始已廢棄
print (time.time())  #返回當前系統時間戳
print (time.ctime())  #輸出Tue Jan 26 18:23:48 2016 ,當前系統時間
print (time.ctime(time.time() - 86640 ))  #將時間戳轉為字符串格式
print (time.gmtime(time.time() - 86640 ))  #將時間戳轉換成struct_time格式
print (time.localtime(time.time() - 86640 ))  #將時間戳轉換成struct_time格式,但返回 的本地時間
print (time.mktime(time.localtime()))  #與time.localtime()功能相反,將struct_time格式轉回成時間戳格式
#time.sleep(4) #sleep
print (time.strftime( "%Y-%m-%d %H:%M:%S" ,time.gmtime()) )  #將struct_time格式轉成指定的字符串格式
print (time.strptime( "2016-01-28" , "%Y-%m-%d" ) )  #將字符串格式轉換成struct_time格式
 
#datetime module
 
print (datetime.date.today())  #輸出格式 2016-01-26
print (datetime.date.fromtimestamp(time.time() - 864400 ) )  #2016-01-16 將時間戳轉成日期格式
current_time  =  datetime.datetime.now()  #
print (current_time)  #輸出2016-01-26 19:04:30.335935
print (current_time.timetuple())  #返回struct_time格式
 
#datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])
print (current_time.replace( 2014 , 9 , 12 ))  #輸出2014-09-12 19:06:24.074900,返回當前時間,但指定的值將被替換
 
str_to_date  =  datetime.datetime.strptime( "21/11/06 16:30" "%d/%m/%y %H:%M" #將字符串轉換成日期格式
new_date  =  datetime.datetime.now()  +  datetime.timedelta(days = 10 #比現在加10天
new_date  =  datetime.datetime.now()  +  datetime.timedelta(days = - 10 #比現在減10天
new_date  =  datetime.datetime.now()  +  datetime.timedelta(hours = - 10 #比現在減10小時
new_date  =  datetime.datetime.now()  +  datetime.timedelta(seconds = 120 #比現在+120s
print (new_date)
 

6、shutil模塊

高級的 文件、文件夾、壓縮包 處理模塊

shutil.copyfileobj(fsrc, fdst[, length])
將文件內容拷貝到另一個文件中,可以部分內容

shutil.copyfile(src, dst) 拷貝文件

shutil.copymode(src, dst)

僅拷貝權限。內容、組、用戶均不變

shutil.copystat(src, dst)

拷貝狀態的信息,包括:mode bits, atime, mtime, flags

shutil.copy(src, dst)

拷貝文件和權限

shutil.copy2(src, dst)

拷貝文件和狀態信息

shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
遞歸的去拷貝文件

例如:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

shutil.rmtree(path[, ignore_errors[, onerror]])

遞歸的去刪除文件

shutil.move(src, dst)
遞歸的去移動文件

shutil.make_archive(base_name, format,...)

創建壓縮包並返回文件路徑,例如:zip、tar

  • base_name: 壓縮包的文件名,也可以是壓縮包的路徑。只是文件名時,則保存至當前目錄,否則保存至指定路徑,
    如:www                        =>保存至當前路徑
    如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
  • format: 壓縮包種類,“zip”, “tar”, “bztar”,“gztar”
  • root_dir: 要壓縮的文件夾路徑(默認當前目錄)
  • owner: 用戶,默認當前用戶
  • group: 組,默認當前組
  • logger: 用於記錄日志,通常是logging.Logger對象
1
2
3
4
5
6
7
8
9
#將 /Users/wupeiqi/Downloads/test 下的文件打包放置當前程序目錄
 
import  shutil
ret  =  shutil.make_archive( "wwwwwwwwww" 'gztar' , root_dir = '/Users/wupeiqi/Downloads/test' )
 
 
#將 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目錄
import  shutil
ret  =  shutil.make_archive( "/Users/wupeiqi/wwwwwwwwww" 'gztar' , root_dir = '/Users/wupeiqi/Downloads/test' )

shutil 對壓縮包的處理是調用 ZipFile 和 TarFile 兩個模塊來進行的,

 

7、ConfigParser

用於對特定的配置進行操作,當前模塊的名稱在 python 3.x 版本中變更為 configparser。

1.基本的讀取配置文件

-read(filename) 直接讀取ini文件內容

-sections() 得到所有的section,並以列表的形式返回

-options(section) 得到該section的所有option

-items(section) 得到該section的所有鍵值對

-get(section,option) 得到section中option的值,返回為string類型

-getint(section,option) 得到section中option的值,返回為int類型,還有相應的getboolean()和getfloat() 函數。

 

2.基本的寫入配置文件

-add_section(section) 添加一個新的section

-set( section, option, value) 對section中的option進行設置,需要調用write將內容寫入配置文件。

 

3.Python的ConfigParser Module中定義了3個類對INI文件進行操作。

分別是RawConfigParser、ConfigParser、 SafeConfigParser。

RawCnfigParser是最基礎的INI文件讀取類;

ConfigParser、 SafeConfigParser支持對%(value)s變量的解析。 

 

設定配置文件test.conf


[portal] 

url = http://%(host)s:%(port)s/Portal 

host = localhost 

port = 8080 


使用RawConfigParser:

 


import ConfigParser 

file1 = ConfigParser.RawConfigParser()

file1.read('aa.txt')

print(file1.get('portal','url'))

得到終端輸出:

http://%(host)s:%(port)s/Portal


 

使用ConfigParser:


import ConfigParser 

file2 = ConfigParser.ConfigParser()

file2.read('aa.txt')
print(file2.get('portal','url'))

得到終端輸出:

http://localhost:8080/Portal


 

使用SafeConfigParser:


import ConfigParser 

 

cf = ConfigParser.SafeConfigParser() 

file3 = ConfigParser.SafeConfigParser()

file3.read('aa.txt')
print(file3.get('portal','url'))

得到終端輸出(效果同ConfigParser):

http://localhost:8080/Portal

 

舉例說明:

# 注釋1
; 注釋2
 
[section1]
k1 = v1
k2:v2
 
[section2]
k1 = v1

import ConfigParser
 
config = ConfigParser.ConfigParser()
config.read('i.cfg')
 
# ########## 讀 ##########
#secs = config.sections()
#print secs
#options = config.options('group2')
#print options
 
#item_list = config.items('group2')
#print item_list
 
#val = config.get('group1','key')
#val = config.getint('group1','key')
 
# ########## 改寫 ##########
#sec = config.remove_section('group1')
#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"))
configparser

 

8、logging模塊:

 

用於便捷記錄日志且線程安全的模塊

 

1.簡單的將日志打印到屏幕

 

import logging

logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

 

屏幕上打印:
WARNING:root:This is warning message

默認情況下,logging將日志打印到屏幕,日志級別為WARNING;
日志級別大小關系為:CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET,當然也可以自己定義日志級別。

2.通過logging.basicConfig函數對日志的輸出格式及方式做相關配置

import logging

logging.basicConfig(level=logging.DEBUG,
                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                datefmt='%a, %d %b %Y %H:%M:%S',
                filename='myapp.log',
                filemode='w')
    
logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

 

./myapp.log文件中內容為:
Sun, 24 May 2009 21:48:54 demo2.py[line:11] DEBUG This is debug message
Sun, 24 May 2009 21:48:54 demo2.py[line:12] INFO This is info message
Sun, 24 May 2009 21:48:54 demo2.py[line:13] WARNING This is warning message

logging.basicConfig函數各參數:
filename: 指定日志文件名
filemode: 和file函數意義相同,指定日志文件的打開模式,'w'或'a'
format: 指定輸出的格式和內容,format可以輸出很多有用信息,如上例所示:
 %(levelno)s: 打印日志級別的數值
 %(levelname)s: 打印日志級別名稱
 %(pathname)s: 打印當前執行程序的路徑,其實就是sys.argv[0]
 %(filename)s: 打印當前執行程序名
 %(funcName)s: 打印日志的當前函數
 %(lineno)d: 打印日志的當前行號
 %(asctime)s: 打印日志的時間
 %(thread)d: 打印線程ID
 %(threadName)s: 打印線程名稱
 %(process)d: 打印進程ID
 %(message)s: 打印日志信息
datefmt: 指定時間格式,同time.strftime()
level: 設置日志級別,默認為logging.WARNING
stream: 指定將日志的輸出流,可以指定輸出到sys.stderr,sys.stdout或者文件,默認輸出到sys.stderr,當stream和filename同時指定時,stream被忽略

3.將日志同時輸出到文件和屏幕

import logging

logging.basicConfig(level=logging.DEBUG,
                format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                datefmt='%a, %d %b %Y %H:%M:%S',
                filename='myapp.log',
                filemode='w')

#################################################################################################
#定義一個StreamHandler,將INFO級別或更高的日志信息打印到標准錯誤,並將其添加到當前的日志處理對象#
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
#################################################################################################

logging.debug('This is debug message')
logging.info('This is info message')
logging.warning('This is warning message')

 

屏幕上打印:
root        : INFO     This is info message
root        : WARNING  This is warning message

./myapp.log文件中內容為:
Sun, 24 May 2009 21:48:54 demo2.py[line:11] DEBUG This is debug message
Sun, 24 May 2009 21:48:54 demo2.py[line:12] INFO This is info message
Sun, 24 May 2009 21:48:54 demo2.py[line:13] WARNING This is warning message

4.logging之日志回滾

import logging
from logging.handlers import RotatingFileHandler

#################################################################################################
#定義一個RotatingFileHandler,最多備份5個日志文件,每個日志文件最大10M
Rthandler = RotatingFileHandler('myapp.log', maxBytes=10*1024*1024,backupCount=5)
Rthandler.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
Rthandler.setFormatter(formatter)
logging.getLogger('').addHandler(Rthandler)
################################################################################################

從上例和本例可以看出,logging有一個日志處理的主對象,其它處理方式都是通過addHandler添加進去的。
logging的幾種handle方式如下:

 

logging.StreamHandler: 日志輸出到流,可以是sys.stderr、sys.stdout或者文件
logging.FileHandler: 日志輸出到文件

日志回滾方式,實際使用時用RotatingFileHandler和TimedRotatingFileHandler
logging.handlers.BaseRotatingHandler
logging.handlers.RotatingFileHandler
logging.handlers.TimedRotatingFileHandler

logging.handlers.SocketHandler: 遠程輸出日志到TCP/IP sockets
logging.handlers.DatagramHandler:  遠程輸出日志到UDP sockets
logging.handlers.SMTPHandler:  遠程輸出日志到郵件地址
logging.handlers.SysLogHandler: 日志輸出到syslog
logging.handlers.NTEventLogHandler: 遠程輸出日志到Windows NT/2000/XP的事件日志
logging.handlers.MemoryHandler: 日志輸出到內存中的制定buffer
logging.handlers.HTTPHandler: 通過"GET"或"POST"遠程輸出到HTTP服務器

 

由於StreamHandler和FileHandler是常用的日志處理方式,所以直接包含在logging模塊中,而其他方式則包含在logging.handlers模塊中,
上述其它處理方式的使用請參見python2.5手冊!

5.通過logging.config模塊配置日志

#logger.conf

###############################################

[loggers]
keys=root,example01,example02

[logger_root]
level=DEBUG
handlers=hand01,hand02

[logger_example01]
handlers=hand01,hand02
qualname=example01
propagate=0

[logger_example02]
handlers=hand01,hand03
qualname=example02
propagate=0

###############################################

[handlers]
keys=hand01,hand02,hand03

[handler_hand01]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stderr,)

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form01
args=('myapp.log', 'a')

[handler_hand03]
class=handlers.RotatingFileHandler
level=INFO
formatter=form02
args=('myapp.log', 'a', 10*1024*1024, 5)

###############################################

[formatters]
keys=form01,form02

[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
datefmt=%a, %d %b %Y %H:%M:%S

[formatter_form02]
format=%(name)-12s: %(levelname)-8s %(message)s
datefmt=

上例3:

import logging
import logging.config

logging.config.fileConfig("logger.conf")
logger = logging.getLogger("example01")

logger.debug('This is debug message')
logger.info('This is info message')
logger.warning('This is warning message')

上例4:

 

import logging
import logging.config

logging.config.fileConfig("logger.conf")
logger = logging.getLogger("example02")

logger.debug('This is debug message')
logger.info('This is info message')
logger.warning('This is warning message')

 

 

9、shelve 模塊

   shelve模塊是一個簡單的k,v將內存數據通過文件持久化的模塊,可以持久化任何pickle可支持的python數據格式

   shelve是一額簡單的數據存儲方案,他只有一個函數就是open(),這個函數接收一個參數就是文件名,然后返回一個shelf對象,你可以用他來存儲東西,就可以簡單的把他當作一個字典,當你存儲完畢的時候,就調用close函數來關閉

 1 import shelve
 2 
 3 d = shelve.open('shelve_file') #打開一個文件
 4 
 5 class Test(object): 6 def __init__(self,n): 7 self.a = n 8 9 10 t = Test(123) 11 t2 = Test(123334) 12 13 name = ["alex","rain","test"] 14 d["test"] = name #持久化列表 15 d["t1"] = t #持久化類 16 d["t2"] = t2 17 18 d.close() 19 20 f = shelve.open('shelve_file') 21 print(f['t1'].a) 22 print(f['test'])
23 f.close

 

則會生成三類文件shelve_file.dat,shelve_file.dir,shelve_file.bak用來充放數據

多關注其中的writeback=True參數

詳情見shelve模塊:
"""Manage shelves of pickled objects.

A "shelf" is a persistent, dictionary-like object.  The difference
with dbm databases is that the values (not the keys!) in a shelf can
be essentially arbitrary Python objects -- anything that the "pickle"
module can handle.  This includes most class instances, recursive data
types, and objects containing lots of shared sub-objects.  The keys
are ordinary strings.

To summarize the interface (key is a string, data is an arbitrary
object):

        import shelve
        d = shelve.open(filename) # open, with (g)dbm filename -- no suffix

        d[key] = data   # store data at key (overwrites old data if
                        # using an existing key)
        data = d[key]   # retrieve a COPY of the data at key (raise
                        # KeyError if no such key) -- NOTE that this
                        # access returns a *copy* of the entry!
        del d[key]      # delete data stored at key (raises KeyError
                        # if no such key)
        flag = key in d # true if the key exists
        list = d.keys() # a list of all existing keys (slow!)

        d.close()       # close it

Dependent on the implementation, closing a persistent dictionary may
or may not be necessary to flush changes to disk.

Normally, d[key] returns a COPY of the entry.  This needs care when
mutable entries are mutated: for example, if d[key] is a list,
        d[key].append(anitem)
does NOT modify the entry d[key] itself, as stored in the persistent
mapping -- it only modifies the copy, which is then immediately
discarded, so that the append has NO effect whatsoever.  To append an
item to d[key] in a way that will affect the persistent mapping, use:
        data = d[key]
        data.append(anitem)
        d[key] = data

To avoid the problem with mutable entries, you may pass the keyword
argument writeback=True in the call to shelve.open.  When you use:
        d = shelve.open(filename, writeback=True)
then d keeps a cache of all entries you access, and writes them all back
to the persistent mapping when you call d.close().  This ensures that
such usage as d[key].append(anitem) works as intended.

However, using keyword argument writeback=True may consume vast amount
of memory for the cache, and it may make d.close() very slow, if you
access many of d's entries after opening it in this way: d has no way to
check which of the entries you access are mutable and/or which ones you
actually mutate, so it must cache, and write back at close, all of the
entries that you access.  You can call d.sync() to write back all the
entries in the cache, and empty the cache (d.sync() also synchronizes
the persistent dictionary on disk, if feasible).
"""

from pickle import Pickler, Unpickler
from io import BytesIO

import collections

__all__ = ["Shelf", "BsdDbShelf", "DbfilenameShelf", "open"]

class _ClosedDict(collections.MutableMapping):
    'Marker for a closed dict.  Access attempts raise a ValueError.'

    def closed(self, *args):
        raise ValueError('invalid operation on closed shelf')
    __iter__ = __len__ = __getitem__ = __setitem__ = __delitem__ = keys = closed

    def __repr__(self):
        return '<Closed Dictionary>'


class Shelf(collections.MutableMapping):
    """Base class for shelf implementations.

    This is initialized with a dictionary-like object.
    See the module's __doc__ string for an overview of the interface.
    """

    def __init__(self, dict, protocol=None, writeback=False,
                 keyencoding="utf-8"):
        self.dict = dict
        if protocol is None:
            protocol = 3
        self._protocol = protocol
        self.writeback = writeback
        self.cache = {}
        self.keyencoding = keyencoding

    def __iter__(self):
        for k in self.dict.keys():
            yield k.decode(self.keyencoding)

    def __len__(self):
        return len(self.dict)

    def __contains__(self, key):
        return key.encode(self.keyencoding) in self.dict

    def get(self, key, default=None):
        if key.encode(self.keyencoding) in self.dict:
            return self[key]
        return default

    def __getitem__(self, key):
        try:
            value = self.cache[key]
        except KeyError:
            f = BytesIO(self.dict[key.encode(self.keyencoding)])
            value = Unpickler(f).load()
            if self.writeback:
                self.cache[key] = value
        return value

    def __setitem__(self, key, value):
        if self.writeback:
            self.cache[key] = value
        f = BytesIO()
        p = Pickler(f, self._protocol)
        p.dump(value)
        self.dict[key.encode(self.keyencoding)] = f.getvalue()

    def __delitem__(self, key):
        del self.dict[key.encode(self.keyencoding)]
        try:
            del self.cache[key]
        except KeyError:
            pass

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.close()

    def close(self):
        self.sync()
        try:
            self.dict.close()
        except AttributeError:
            pass
        # Catch errors that may happen when close is called from __del__
        # because CPython is in interpreter shutdown.
        try:
            self.dict = _ClosedDict()
        except (NameError, TypeError):
            self.dict = None

    def __del__(self):
        if not hasattr(self, 'writeback'):
            # __init__ didn't succeed, so don't bother closing
            # see http://bugs.python.org/issue1339007 for details
            return
        self.close()

    def sync(self):
        if self.writeback and self.cache:
            self.writeback = False
            for key, entry in self.cache.items():
                self[key] = entry
            self.writeback = True
            self.cache = {}
        if hasattr(self.dict, 'sync'):
            self.dict.sync()


class BsdDbShelf(Shelf):
    """Shelf implementation using the "BSD" db interface.

    This adds methods first(), next(), previous(), last() and
    set_location() that have no counterpart in [g]dbm databases.

    The actual database must be opened using one of the "bsddb"
    modules "open" routines (i.e. bsddb.hashopen, bsddb.btopen or
    bsddb.rnopen) and passed to the constructor.

    See the module's __doc__ string for an overview of the interface.
    """

    def __init__(self, dict, protocol=None, writeback=False,
                 keyencoding="utf-8"):
        Shelf.__init__(self, dict, protocol, writeback, keyencoding)

    def set_location(self, key):
        (key, value) = self.dict.set_location(key)
        f = BytesIO(value)
        return (key.decode(self.keyencoding), Unpickler(f).load())

    def next(self):
        (key, value) = next(self.dict)
        f = BytesIO(value)
        return (key.decode(self.keyencoding), Unpickler(f).load())

    def previous(self):
        (key, value) = self.dict.previous()
        f = BytesIO(value)
        return (key.decode(self.keyencoding), Unpickler(f).load())

    def first(self):
        (key, value) = self.dict.first()
        f = BytesIO(value)
        return (key.decode(self.keyencoding), Unpickler(f).load())

    def last(self):
        (key, value) = self.dict.last()
        f = BytesIO(value)
        return (key.decode(self.keyencoding), Unpickler(f).load())


class DbfilenameShelf(Shelf):
    """Shelf implementation using the "dbm" generic dbm interface.

    This is initialized with the filename for the dbm database.
    See the module's __doc__ string for an overview of the interface.
    """

    def __init__(self, filename, flag='c', protocol=None, writeback=False):
        import dbm
        Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback)


def open(filename, flag='c', protocol=None, writeback=False):
    """Open a persistent dictionary for reading and writing.

    The filename parameter is the base filename for the underlying
    database.  As a side-effect, an extension may be added to the
    filename and more than one file may be created.  The optional flag
    parameter has the same interpretation as the flag parameter of
    dbm.open(). The optional protocol parameter specifies the
    version of the pickle protocol (0, 1, or 2).

    See the module's __doc__ string for an overview of the interface.
    """

    return DbfilenameShelf(filename, flag, protocol, writeback)

shelve
shelve

 

但上面的使用有一個潛在的小問題,如下:
  1. >>> import shelve  
  2. >>> s = shelve.open('test.dat')  
  3. >>> s['x'] = ['a', 'b', 'c']  
  4. >>> s['x'].append('d')  
  5. >>> s['x']  
  6. ['a', 'b', 'c']  
存儲的d到哪里去了呢?其實很簡單,d沒有寫回,你把['a', 'b', 'c']存到了x,當你再次讀取s['x']的時候,s['x']只是一個拷貝,而你沒有將拷貝寫回,所以當你再次讀取s['x']的時候,它又從源中讀取了一個拷貝,所以,你新修改的內容並不會出現在拷貝中,解決的辦法就是,第一個是利用一個緩存的變量,如下所示
  1. >>> temp = s['x']  
  2. >>> temp.append('d')  
  3. >>> s['x'] = temp  
  4. >>> s['x']  
  5. ['a', 'b', 'c', 'd']  
在python2.4中有了另外的方法,就是把open方法的writeback參數的值賦為True,這樣的話,你open后所有的內容都將在cache中,當你close的時候,將全部一次性寫到硬盤里面。如果數據量不是很大的時候,建議這么做。
 
例:基於shelve的簡單數據庫的代碼
#database.py  
import sys, shelve  
  
def store_person(db):  
    """ 
    Query user for data and store it in the shelf object 
    """  
    pid = raw_input('Enter unique ID number: ')  
    person = {}  
    person['name'] = raw_input('Enter name: ')  
    person['age'] = raw_input('Enter age: ')  
    person['phone'] = raw_input('Enter phone number: ')  
    db[pid] = person  
  
def lookup_person(db):  
    """ 
    Query user for ID and desired field, and fetch the corresponding data from 
    the shelf object 
    """  
    pid = raw_input('Enter ID number: ')  
    field = raw_input('What would you like to know? (name, age, phone) ')  
    field = field.strip().lower()  
    print field.capitalize() + ':', \  
        db[pid][field]  
  
def print_help():  
    print 'The available commons are: '  
    print 'store  :Stores information about a person'  
    print 'lookup :Looks up a person from ID number'  
    print 'quit   :Save changes and exit'  
    print '?      :Print this message'  
  
def enter_command():  
    cmd = raw_input('Enter command (? for help): ')  
    cmd = cmd.strip().lower()  
    return cmd  
  
def main():  
    database = shelve.open('database.dat')  
    try:   
        while True:  
            cmd = enter_command()  
            if cmd == 'store':  
                store_person(database)  
            elif cmd == 'lookup':  
                lookup_person(database)  
            elif cmd == '?':  
                print_help()  
            elif cmd == 'quit':  
                return   
    finally:  
        database.close()  
if __name__ == '__main__': 
    main()  

shelve數據庫實例
shelve數據庫實例

 

 10、xml模塊

xml是實現不同語言或程序之間進行數據交換的協議,跟json差不多,但json使用起來更簡單,不過,古時候,在json還沒誕生的黑暗年代,大家只能選擇用xml呀,至今很多傳統公司如金融行業的很多系統的接口還主要是xml。

xml的格式如下,就是通過<>節點來區別數據結構的:

<?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文件格式
xml文件格式

 

xml協議在各個語言里的都是支持的,在python中可以用以下模塊操作xml 

在實際應用中,需要對xml配置文件進行實時修改, 

 1.增加、刪除 某些節點

 2.增加,刪除,修改某個節點下的某些屬性

 3.增加,刪除,修改某些節點的文本

 

實現思想:

使用ElementTree,先將文件讀入,解析成樹,之后,根據路徑,可以定位到樹的每個節點,再對節點進行修改,最后直接將其輸出

 

具體代碼如下:

from xml.etree.ElementTree import ElementTree

def read_xml(in_path):
    '''''讀取並解析xml文件
       in_path: xml路徑
       return: ElementTree'''
    tree = ElementTree()
    tree.parse(in_path)
    root = tree.getroot()
    return(tree,root)

def write_xml(tree, out_path):
    '''''將xml文件寫出
       tree: xml樹
       out_path: 寫出路徑'''
    tree.write(out_path, encoding="utf-8",xml_declaration=True)

def if_match(node, kv_map):
    '''''判斷某個節點是否包含所有傳入參數屬性
       node: 節點
       kv_map: 屬性及屬性值組成的map'''
    for key in kv_map:
        #if node.get(key) != kv_map.get(key):
        if node.get(key) != kv_map[key]:
            return False
    return True

def if_match_text(node, text,mode='eq'):
    '''''判斷某個節點是否包含所有傳入參數屬性
       node: 節點
       text: 標簽具體值
       mode: 數值判斷大小'''

    if mode == 'eq':
        express = "{0} == {1}"
    elif mode == 'gt':
        express = "{0} > {1}"
    elif mode == 'lt':
        express = "{0} < {1}"
    else:
        print('the mode is error')
        return False

    flag = eval(express.format(int(node.text),text))

    if flag:
        return True
    return False


#---------------search -----

def find_nodes(tree, path):
    '''''查找某個路徑匹配的所有節點
       tree: xml樹
       path: 節點路徑'''
    return tree.findall(path)


def get_node_by_keyvalue(nodelist, kv_map):
    '''''根據屬性及屬性值定位符合的節點,返回節點
       nodelist: 節點列表
       kv_map: 匹配屬性及屬性值map'''
    result_nodes = []
    for node in nodelist:
        if if_match(node, kv_map):
            result_nodes.append(node)
    return result_nodes

#---------------change -----

def change_node_properties(nodelist, kv_map, is_delete=False):
    '''''修改/增加 /刪除 節點的屬性及屬性值
       nodelist: 節點列表
       kv_map:屬性及屬性值map'''
    for node in nodelist:
        for key in kv_map:
            if is_delete:
                if key in node.attrib:
                    del node.attrib[key]
            else:
                node.set(key, kv_map.get(key))

def change_node_text(nodelist, text, is_add=False, is_delete=False):
    '''''改變/增加/刪除一個節點的文本
       nodelist:節點列表
       text : 更新后的文本'''
    for node in nodelist:
        if is_add:
            node.text = text * 3
        elif is_delete:
            node.text = ""
        else:
            node.text = text

def create_node(tag, property_map, content):
    '''''新造一個節點
       tag:節點標簽
       property_map:屬性及屬性值map
       content: 節點閉合標簽里的文本內容7
       return 新節點'''
    element = Element(tag, property_map)
    element.text = content
    return element

def add_child_node(nodelist, element):
    '''''給一個節點添加子節點
       nodelist: 節點列表
       element: 子節點'''
    for node in nodelist:
        node.append(element)

def del_node_by_tagkeyvalue(nodelist, tag, kv_map):
    '''''通過屬性及屬性值定位一個節點,並刪除之
       nodelist: 父節點列表
       tag:子節點標簽
       kv_map: 屬性及屬性值列表'''
    for parent_node in nodelist:
        children = parent_node.getchildren()

        for child in children:
            if child.tag == tag and if_match(child, kv_map):
                parent_node.remove(child)


def del_node_by_tagtext(nodelist, tag, text,mode='eq',flag=1):
    '''''通過屬性及屬性值定位一個節點,並刪除之
       nodelist: 父節點列表
       tag:子節點標簽
       text: 標簽具體值'''
    for parent_node in nodelist:

        children = parent_node.getchildren()

        for child in children:
            if child.tag == tag and if_match_text(child,text,mode):
                if flag == 1:
                    parent_node.remove(child)
                else:
                    root.remove(parent_node)


if __name__ == "__main__":

    #1. 讀取xml文件
    (tree,root) = read_xml("server.xml")
    print(root)


    #2. 屬性修改
      #A. 找到父節點
    nodes = find_nodes(tree, "country/neighbor")

      #B. 通過屬性准確定位子節點
    result_nodes = get_node_by_keyvalue(nodes, {"direction":"E"})

      #C. 修改節點屬性
    change_node_properties(result_nodes, {"age": "10","position":'asiaasia'})

      #D. 刪除節點屬性
    change_node_properties(result_nodes, {"age": "10"},is_delete=True)

    #3. 節點修改
      #A.新建節點
    a = create_node("person", {"age":"15","money":"200000"}, "this is the firest content")

      #B.插入到父節點之下
    add_child_node(result_nodes, a)


    #4. 刪除節點
       #定位父節點
    del_parent_nodes = find_nodes(tree, "country")

       #根據attrib准確定位子節點並刪除之
    target_del_node = del_node_by_tagkeyvalue(del_parent_nodes, "neighbor", {"direction":"N"})

       #根據text准確定位子節點並刪除之
    target_del_node = del_node_by_tagtext(del_parent_nodes, "gdppc",60000,'gt',1)

       #根據text准確定位country並刪除之
    target_del_element = del_node_by_tagtext(del_parent_nodes, "rank",20,'gt',0)

    #5. 修改節點文本
       #定位節點
    text_nodes = get_node_by_keyvalue(find_nodes(tree, "country/neighbor"), {"direction":"E"})
    change_node_text(text_nodes, "east",is_add=True)


    #6. 輸出到結果文件
    write_xml(tree,"test.xml")

xml增刪改查
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) #打印生成的格式

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM