文章出處

Python第十一天    異常處理  glob模塊和shlex模塊    打開外部程序和subprocess模塊  subprocess類  Pipe管道  operator模塊   sorted函數   生成器  walk模塊   hashlib模塊

 

 

目錄

Pycharm使用技巧(轉載)

Python第一天 安裝 shell 文件

Python第二天 變量 運算符與表達式 input()與raw_input()區別 字符編碼

Python第三天 序列 數據類型 數值 字符串 列表 元組 字典

Python第四天 流程控制 ifelse條件判斷 forwhile循環

Python第五天 文件訪問 for循環訪問文件 while循環訪問文件 字符串的startswith函數和split函數

Python第六天 類型轉換

Python第七天 函數 函數參數 函數變量 函數返回值 多類型傳值 冗余參數 函數遞歸調用 匿名函數 內置函數 列表表達式/列表重寫

Python第八天 模塊 包 全局變量和內置變量__name__ Python path

Python第九天 面向對象 類定義 類的屬性 類的方法 內部類 垃圾回收機制 類的繼承

Python第十天 print >> f,和fd.write()的區別 stdout的buffer 標準輸入 標準輸出 標準錯誤 重定向

Python第十一天 異常處理 glob模塊和shlex模塊 打開外部程序和subprocess模塊 subprocess類 Pipe管道 operator模塊 sorted函數 生成器 walk模塊 hashlib模塊

Python第十二天   收集主機信息   正則表達式   正則表達式  無名分組   有名分組

Python第十三天   django 1.6   導入模板   定義數據模型   訪問數據庫   GET和POST方法    SimpleCMDB項目   urllib模塊   urllib2模塊  httplib模塊  django和web服務器整合  wsgi模塊   gunicorn模塊

Python第十四天 序列化  pickle模塊  cPickle模塊  JSON模塊  API的兩種格式

 

 


python標準庫,python自帶的模塊
不是python標準庫,不是python自帶的模塊都需要安裝第三方軟件

 

 

 

hashlib模塊
相當于shell里面的md5sum命令
一定要去除換行符

import hashlib
md5 = hashlib.md5()
md5.update('hello')
md5.hexdigest()
'5d41402abc4b2a76b9719d911017c592'


等價于 echo -n hello |md5sum
5d41402abc4b2a76b9719d911017c592

md5.update方法會追加后來添加的值
md5.update('a')
md5.update('b')
#計算出來的是ab的md5值,也就是md5.update('ab')
md5.hexdigest()

示例
#!/usr/bin/env python

import sys
import hashlib

def md5sum(f):
    m = hashlib.md5()
    with open(f) as fd:
        while True:
            data = fd.read(4096)
            if data:
                m.update(data)
            else:
                break
    return m.hexdigest()

if __name__ == '__main__':
    try:
        print md5sum(sys.argv[1])
    except IndexError:
        print "%s follow a argument" % __file__

----------------------------------------------------------

walk模塊

os.walk

迭代目錄里文件
os.walk返回的是1個元組(生成器對象),這個元組有3個元素,分別是dirpath, dirnames, filenames,所以使用3個變量p,d,f去接收這3個元素,即for p,d,f in a
filenames是個列表,對應的是f,所以對f進行for循環遍歷,取里面的每一個文件名,最后把文件名組織成帶路徑的,即os.path.join(p,i)。

 

示例
#!/usr/bin/env python

import os
import sys
import hashlib

def md5sum(f):
m = hashlib.md5()
with open(f) as fd:
while True:
data = fd.read(4096)
if data:
m.update(data)
else:
break
return m.hexdigest()

def file_md5(topdir):
a = os.walk(topdir)
for p, d, f in a:
for i in f:
fn = os.path.join(p,i)
md5 = md5sum(fn)
yield "%s %s" % (md5, fn)

if __name__ == '__main__':
lines = ''
try:
topdir = sys.argv[1]
except IndexError:
print "%s follow a dir"
sys.exit()
gen = file_md5(topdir)
for i in gen:
lines += i+'\n'
print lines
print hashlib.md5(lines).hexdigest()

 

 

-----------------------------------------------------------------

生成器

生成器是一次生成一個值的特殊類型函數。可以將其視為可恢復函數。調用該函數將返回一個可用于生成連續 x 值的生成器【Generator】,簡單的說就是在函數的執行過程中,yield語句會把你需要的值返回給調用生成器的地方,然后退出函數,下一次調用生成器函數的時候又從上次中斷的地方開始執行,而生成器內的所有變量參數都會被保存下來供下一次使用。

 

生成器對象
mygenerator = (x*x for x in range(4))  #用小括號而不是中括號,中括號是列表重寫
for i in mygenerator : print i 調用next方法


next()方法
mygenerator.next()

#文件也是生成器
f=open('/etc/hosts')
for i in f : print i 調用next方法


yield
當調用這個函數的時候,函數內部的代碼并不立馬執行 ,
這個函數只是返回一個生成器對象
當使用for進行迭代的時候,函數內的代碼才會被執行
因為函數里出現了yield,我們把這個函數叫做生成器
當產生一個生成器的時候,每遍歷一次,yield就會吐出一個值,這個值是不會保存在內存里的,除非有其他變量來接收這個值。


>>> def h():
... print 'one'
... yield 1
... print 'two'
... yield 2
... print 'three'
... yield 3
...
>>> c = h()
>>> c.next()

def f(n):
    for i in range(n):
    yield i

a = f(5)
a.next()
for i in a: print i

生成器是一個可迭代的對象,可以對可迭代對象進行遍歷,比如字符串,列表等,都是可迭代對象

return與yield區別
return的時候這個函數的局部變量就都銷毀了
所以return是得到所有結果之后的返回
yield是產生了一個可以恢復的函數(生成器),恢復了局部變量。
生成器只有在調用.next()時才運行函數生成一個結果

---------------------------------------------------------------
operator模塊
sorted函數

按字典值排序


第一個參數是必須的,必須傳入一個可迭代對象用來排序,其他參數都有默認值
reverse表示正向還是反向排序
key表示排序的值,如果是字典通過operator來選擇key排序還是value排序
返回值是一個列表
sorted(可迭代對象,cmp,key,reverse)

operator.itemgetter(0):按照key來排序
operator.itemgetter(1):按照value來排序

按照字典value排序,類似sort -k命令
import operator
x = {1:2, 3:4, 4:3, 2:1, 0:0}
sorted_x = sorted(x.iteritems(), key=operator.itemgetter(1))
sorted_y = sorted(x.iteritems(), key=operator.itemgetter(1), reverse=True)



找出占用空間大的文件
os.walk
os.path.getsize
dict sort (top10)
#!/usr/bin/env python

import os
import sys
import operator

def gen_dic(topdir):
    dic = {}
    a = os.walk(topdir)
    for p, d, f in a:
        for i in f:
            fn = os.path.join(p, i)
            f_size = os.path.getsize(fn)
            dic[fn] = f_size
    return dic

if __name__ == '__main__':
    dic = gen_dic(sys.argv[1])
    sorted_dic = sorted(dic.iteritems(), key=operator.itemgetter(1), reverse=True)
    for k, v in sorted_dic[:10]:
        print k, '-->', v

 


-----------------------------------------------------------------------

打開外部程序和subprocess模塊  subprocess類  Pipe管道

os.system:輸出在終端上,捕獲不到
os.popen:只能捕捉到標準輸出,捕捉不到標準錯誤輸出
os.popen2:返回2個對象,一個是標準輸入,一個標準輸出
os.popen3:返回3個對象,標準輸入,標準輸出,標準錯誤輸出
os.popen4:已經廢棄,不建議使用,用subprocess模塊代替,返回2個對象,pipe_in和pipe_out_err

os.popenX都不建議使用,使用subprocess模塊代替os.popenX


示例
import os

s = os.system('ls')
print s # 只能看到命令成功與否的返回值,不能保存命令執行結果

pipe_out = os.popen('ls')
pipe_out.wait()   # wait方法,父進程等待子進程執行完才返回
pipe_out.read() # 讀取命令執行結果

(pipe_in, pipe_out) = os.popen2('sort')
pipe_in.write('z\n')
pipe_in.write('a\n')
pipe_in.close() # 關閉管道 關閉文件
pipe_out.read()

pipe_in, pipe_out, pipe_err = os.popen3('sort')
pipe_err.read()

pipe_in, pipe_out_err = os.popen4('sort')


subprocess
import subprocess
subprocess.call(['ls', '-l','--color','/root']
subprocess.call('ls -l --color /root', shell=True) # shell=True表示命令在shell下執行,默認情況shell=False
subprocess.call(['ls','-l', '--color', '/root']) 等價于subprocess.call('ls -l --color /root', shell=True)

輸出不能捕捉到,與os.system一樣
subprocess.check_call(['mkdir', '/tmp/aaa'])
check_call會拋python異常

call和check_call跟os.popenX不一樣,不需要調用wait方法,父進程會默認等待子進程執行完才返回

 

 

 

subprocess類
subprocess.Popen(['mkdir', 'aaa'],stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
為什麼叫subprocess,調用外部命令的時候實際上是fork出一個子進程子shell來執行

communicate()方法
p.communicate()方法相當于p.stdin.write()、p.stdin.close()與p.stdout.read()這3個方法
p = Popen(['wc'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
p.terminate() #終止子進程
p.wait() #等待子進程
p.pid #子進程的pid
p.returncode #子進程執行完的返回碼

 


Pipe管道
p1 = Popen(['ls'], stdout=PIPE)
p2 = Popen(['grep', 'py'], stdin=p1.stdout, stdout=PIPE)
result = p2.stdout
for i in result:print i,

 

 

----------------------------------------------------------------------------
glob模塊和shlex模塊

 

glob模塊
glob:擴展shell通配符的
import glob
glob.glob('/etc/*.conf')

 

 

shlex模塊
import shlex
cmd = "mysql -u root -p123 -e 'show processlist'"
shlex.split(cmd)

ps ax -o pid,ppid,cmd

shlex.split()能識別引號,認為引號里的為一個元素,例如:
shlex.split('ps -eo "pid lstart"')與'ps -eo "pid lstart"'.split()得到的結果是不一樣的。

 

 

 

 

----------------------------------------------------------------------------

異常處理

NameError 嘗試訪問一個沒有聲明的變量
ImportError 無法引入模塊或包;可能路徑不存在
IndentationError 語法錯誤(的子類);代碼沒有正確對齊
SyntaxError 語法錯誤
IndexError 索引超出序列范圍
KeyError 請求一個不存在的字典關鍵字
IOError 輸入輸出錯誤(比如你要讀的文件不存在)
AttributeError 嘗試訪問未知的對象屬性
ValueError 傳給函數的參數類型不正確,比如給int()函數傳入字符串類型
UnboundLocalError 試圖訪問一個還未被設置的局部變量
KeyboardInterrupt


import subprocess
try:
subprocess.check_call('exit 1', shell=True) # shell里面退出碼非0會觸發異常
except subprocess.CalledProcessError:
print 'call fail'
except Exception, e:
print e
print ‘hello world’

 

自定義異常,繼承Exception根類
class FuncError(Exception):
def __str__(self):
return "I am a funError"

def func():
raise FuncError()

func()
#try:
# func()
#except FuncError, e:
# print e
print 'hello world'

 

#如果不知道異常的類型,就寫Exception,Exception是總的異常
func()
try:
func()
except Exception:
print e

#如果有多個異常,那么只會捕獲一個異常
func()
try:
func()
except NameError:
print e
except IndexError:
print e
except ValueError:
print e

 


異常在try塊里拋。
finally:無論try塊是否拋異常,永遠執行的代碼,通常用來執行關閉文件,斷開服務器連接的功能。

try無異常,才會執行else
語法格式
try:

except:

else:

finally:

 

 



文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 AutoPoster 的頭像
    AutoPoster

    互聯網 - 大數據

    AutoPoster 發表在 痞客邦 留言(0) 人氣()