day5心得

import 模塊html

一、定義:node

模塊:用來從邏輯上組織python代碼(變量、函數、類、邏輯:實現一個功能),本質就是.py結尾的python文件(文件名test.py 模塊名:test)python

2導入方法:git

import test正則表達式

import test,test1算法

from test import t1,t2shell

from test import t1 as  long_test編程

三、import 本質(路徑搜索,搜索路徑)json

導入模塊的本質就是把python文件解釋一遍windows

import test  ----->test.py----->test.py的路徑

導入包的本質就是執行該包下的__init__.py文件

__init__.py 引導到當前的模塊裏 能夠寫  from . import test1

四、導入優化

from test import t1

五、模塊分類

  a:標準庫或內置模塊

  b:開源模塊或第三方模塊

  c:自定義模塊

 

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

一:介紹

模塊定義:模塊就是實現了某個功能的代碼集合,一個模塊能夠定義函數,類和變量。模塊還能夠包括可運行的代碼。

優勢:代碼重用,可維護性高

語法:

導入單一模塊:

1
import  module_name

導入多個模塊

1
import  module_name1,module_name2,......

調用符號:.

1
2
3
import  os
print (os.sep)
print (os.getcwd())

模塊與文件關係:一個.py文件即一個模塊,反之亦然。

1
2
3
4
5
對於一個模塊test有以下定義:
 
模塊的文件名:test.py
模塊名:test
模塊導入: import  test

 

二:模塊的名稱空間(做用域)

定義:名稱空間就是一個從名稱到對象的關係映射,每一個模塊都定義了本身的名稱空間,即每一個模塊有本身獨立的做用域。

分類:python程序在運行時具備三個名稱空間,內建(__builtin__模塊),全局,局部,python解釋器先加載內建名稱空間,後加載全局名稱空間,最後加載局部名稱空間。

名稱空間與做用域關係:從內往外找,以較內層做用域爲準

 

示例一:

module_a.py

1
2
3
4
5
6
x = 1
 
def  test():
     print ( 'from the module module_a' )
     
module_b.py內容以下

module_b.py

1
2
3
4
x = 2
 
def  test():
     print ( 'from the module module_b' )

test.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import  module_a
import  module_b
 
print (module_a.x)
print (module_b.x)
print (module_a.x + module_b.x)
module_a.test()
module_b.test()
 
運行結果:
1
2
3
from  the module module_a
from  the module module_b

示例二:

module_a.py

1
2
3
4
x = 1
 
def  test():
     print ( 'from the module module_a' ,x)

test.py

1
2
3
4
5
import  module_a
x = 2
print (child_module.x)
child_module.x = 10
print (child_module.x)

 

三:模塊的搜索路徑和路徑搜索

 

模塊導入須要經歷路徑搜索的過程,路徑搜索就是在你預約義的搜素路徑裏查找你想要導入的模塊

若是在預約義路徑爲找到,拋出異常(pycharm的特殊功能除外)

 

自定義模塊b在父級目錄裏(若有特殊須要可使用sys.path.insert()方法)

解決:

1
2
3
4
5
6
import  sys,os
 
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 
import  b
b.test()

 

四:from-import語句和as

 

五:包

定義:包就是一組模塊的集合

包與目錄的區別:包必須包含一個空文件(也能夠有內容)__init__

 

六:阻止屬性導入

 

若是你不想讓某個模塊屬性被 "from module import *" 導入 , 那麼你能夠給你不想導入的屬性名稱加上一個下劃線( _ )。 不過若是你導入了整個模塊或是你顯式地導入某個屬性這個隱藏數據的方法就不起做用了。

 

示例一:

module_test.py

1
2
3
4
5
def  foo():
     print ( 'from the func foo' )
 
def  _bar():
     print ( 'from the func bar' )

test.py

1
2
3
4
5
6
7
from  child_module  import  *
 
foo()
bar()
 
拋出異常:
NameError: name  'bar'  is  not  defined

 

示例二:

module_test.py

1
2
3
4
5
def  foo():
     print ( 'from the func foo' )
 
def  _bar():
     print ( 'from the func bar' )

test.py

1
2
3
4
from  child_module  import  _bar
 
_bar()
正常運行

 

七:導入循環(交叉引用)與import原理

 

導入循環:兩個模塊互相導入

import原理:將導入的模塊執行一遍

 

在python開發過程當中,應儘可能避免導入循環(交叉引用),可是,若是你開發了大型的 Python 工程, 那麼你極可能會陷入這樣的境地。

解決方法:

將 import 語句移到函數的內部,只有在執行到這個模塊時,纔會導入相關模塊。

 

錯誤示範:

b.py

1
2
3
4
5
6
7
8
import  os
import  a
 
def  get_size(file_path):
 
     if  a.file_exists(file_path):
         file_size = os.path.getsize(file_path)
         print ( 'the file %s size is[%s]'  % (file_path,file_size))

a.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import  os
import  b
 
def  file_exists(file_path):
     return  os.path.isfile(file_path)
 
def  download(file_path):
     b.get_size(file_path)
     print ( 'download file %s'  % file_path)
 
def  upload(file_path):
     print ( 'upload file %s'  % file_path)
 
download( 'a.txt' )

解決方法:修改b.py

1
2
3
4
5
6
7
import  os
 
def  get_size(file_path):
     import  a
     if  a.file_exists(file_path):
         file_size = os.path.getsize(file_path)
         print ( 'the file %s size is[%s]'  % (file_path,file_size))

a.py不變

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import  os
import  b
 
def  file_exists(file_path):
     return  os.path.isfile(file_path)
 
def  download(file_path):
     b.get_size(file_path)
     print ( 'download file %s'  % file_path)
 
def  upload(file_path):
     print ( 'upload file %s'  % file_path)
 
download( 'a.txt' )

 

 

模塊分爲三種:

內置模塊

開源模塊

自定義模塊

 

一:自定義模塊

1.定義模塊:即編寫具備某一功能的python文件ftp.py,ftp既模塊名

ftp.py

1
2
3
4
5
def  get(file_path):
     print ( 'download file %s'  % file_path)
     
def  put(file_path):
     print ( 'download file %s'  % file_path)

 

2.模塊導入方式

import ftp

from ftp import get

from ftp import put as upload

from ftp import *

 

3.名稱空間

 

4.import的本質

導入一個模塊本質就是解釋執行一個python文件

導入一個包本質就是解釋該包下的__init__.py文件

 

5.搜索路徑與sys.path操做

 

 

二:開源模塊

 

1.定義模塊:下載安裝

方式一:

 

yum 
pip
apt-get
...

方式二:

下載源碼
解壓源碼
進入目錄
編譯源碼    python setup.py build
安裝源碼    python setup.py install

注:在使用源碼安裝時,須要使用到gcc編譯和python開發環境,因此,須要先執行:

1
2
3
4
yum install gcc
yum install python - devel
apt - get python - dev

安裝成功後,模塊會自動安裝到 sys.path 中的某個目錄中,如:

1
/ usr / lib / python2. 7 / site - packages /

2.導入模塊(同自定義模塊方式)

 

3:paramiko

i:下載安裝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# pycrypto,因爲 paramiko 模塊內部依賴pycrypto,因此先下載安裝pycrypto
  
# 下載安裝 pycrypto
wget http: / / files.cnblogs.com / files / wupeiqi / pycrypto - 2.6 . 1.tar .gz
tar  - xvf pycrypto - 2.6 . 1.tar .gz
cd pycrypto - 2.6 . 1
python setup.py build
python setup.py install
  
# 進入python環境,導入Crypto檢查是否安裝成功
  
# 下載安裝 paramiko
wget http: / / files.cnblogs.com / files / wupeiqi / paramiko - 1.10 . 1.tar .gz
tar  - xvf paramiko - 1.10 . 1.tar .gz
cd paramiko - 1.10 . 1
python setup.py build
python setup.py install
  
# 進入python環境,導入paramiko檢查是否安裝成功

ii.使用模塊

1. 基於用戶名和密碼的 sshclient 方式登陸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import  paramiko
 
# 創建一個sshclient對象
ssh  =  paramiko.SSHClient()
# 容許將信任的主機自動加入到host_allow 列表,此方法必須放在connect方法的前面
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 調用connect方法鏈接服務器
ssh.connect(hostname = '172.16.209.19' ,port = 22 ,username = 'root' ,password = '123' )
# 執行命令
stdin, stdout, stderr  =  ssh.exec_command( 'df -hl' )
# 結果放到stdout中,若是有錯誤將放到stderr中
print (stdout.read().decode())
# 關閉鏈接
ssh.close()

注意:以sshclient方式運行交互式命令須要增長兩行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import  paramiko
 
# 創建一個sshclient對象
ssh  =  paramiko.SSHClient()
# 容許將信任的主機自動加入到host_allow 列表,此方法必須放在connect方法的前面
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 調用connect方法鏈接服務器
ssh.connect(hostname = '172.16.209.119' ,port = 22 ,username = 'root' ,password = '123' )
# 執行命令
stdin, stdout, stderr  =  ssh.exec_command( "passwd lhf" )
# 結果放到stdout中,若是有錯誤將放到stderr中
stdin.write( '123\n' )
stdin.flush()
stdin.write( '123\n' )
stdin.flush()
print (stderr.read())
# 關閉鏈接
ssh.close()

 

2 基於用戶名和密碼的 transport 方式登陸 

其實paramiko.SSHClient().connect()這個方法的內部實現調用的就是Transport().connect()這個方法。因此能夠認爲Transport()是paramiko裏面建立鏈接的通用方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/python
import  paramiko
 
# 實例化一個transport對象
trans  =  paramiko.Transport(( '172.16.209.119' 22 ))
# 創建鏈接
trans.connect(username = 'root' , password = '123' )
 
# 將sshclient的對象的transport指定爲以上的trans
ssh  =  paramiko.SSHClient()
ssh._transport  =  trans
# 執行命令,和傳統方法同樣
stdin, stdout, stderr  =  ssh.exec_command( 'df -hl' )
print (stdout.read().decode())
 
# 關閉鏈接
trans.close()

 

3.基於公鑰密鑰的 SSHClient 方式登陸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python
import  paramiko
 
# 指定本地的RSA私鑰文件,若是創建密鑰對時設置的有密碼,password爲設定的密碼,如無不用指定password參數
pkey  =  paramiko.RSAKey.from_private_key_file( 'D:\id_rsa' ,password = '123456' )
# 創建鏈接
ssh  =  paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname = '172.16.209.119' ,
             port = 22 ,
             username = 'root' ,
             pkey = pkey)
# 執行命令
stdin, stdout, stderr  =  ssh.exec_command( 'df -hl' )
# 結果放到stdout中,若是有錯誤將放到stderr中
print (stdout.read().decode())
# 關閉鏈接
ssh.close()

 

4 .基於密鑰的 Transport 方式登陸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/python
import  paramiko
 
# 指定本地的RSA私鑰文件,若是創建密鑰對時設置的有密碼,password爲設定的密碼,如無不用指定password參數
pkey  =  paramiko.RSAKey.from_private_key_file( 'D:\id_rsa' , password = '123456' )
# 創建鏈接
trans  =  paramiko.Transport(( '172.16.209.119' 22 ))
trans.connect(username = 'root' , pkey = pkey)
 
# 將sshclient的對象的transport指定爲以上的trans
ssh  =  paramiko.SSHClient()
ssh._transport  =  trans
 
# 執行命令,和傳統方法同樣
stdin, stdout, stderr  =  ssh.exec_command( 'df -hl' )
print (stdout.read().decode())
 
# 關閉鏈接
trans.close()

傳文件 SFTP

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/python
import  paramiko
 
# 實例化一個trans對象# 實例化一個transport對象
trans  =  paramiko.Transport(( '172.16.209.119' 22 ))
# 創建鏈接
trans.connect(username = 'root' , password = '123' )
 
# 實例化一個 sftp對象,指定鏈接的通道
sftp  =  paramiko.SFTPClient.from_transport(trans)
# 發送文件
sftp.put(localpath = 'D:\id_rsa' , remotepath = '/tmp/id_rsa' )
# 下載文件
# sftp.get(remotepath, localpath)
trans.close()

 

三:內置模塊

  1. os模塊

用於提供系統級別的操做

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑
os.chdir( "dirname" )  改變當前腳本工做目錄;至關於shell下cd
os.curdir  返回當前目錄: ( '.' )
os.pardir  獲取當前目錄的父目錄字符串名:( '..' )
os.makedirs( 'dirname1/dirname2' )    可生成多層遞歸目錄
os.removedirs( 'dirname1' )    若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir( 'dirname' )    生成單級目錄;至關於shell中mkdir dirname
os.rmdir( 'dirname' )    刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir( 'dirname' )    列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.remove()  刪除一個文件
os.rename( "oldname" , "newname" )  重命名文件 / 目錄
os.stat( 'path/filename' )  獲取文件 / 目錄信息
os.sep    輸出操做系統特定的路徑分隔符,win下爲 "\\",Linux下爲" / "os.linesep    輸出當前平臺使用的行終止符,win下爲" \t\n ",Linux下爲" \n"os.pathsep    輸出用於分割文件路徑的字符串
os.name    輸出字符串指示當前使用平臺。win - > 'nt' ; Linux - > 'posix' os.system( "bash command" )  運行shell命令,直接顯示
os.environ  獲取系統環境變量
os.path.abspath(path)  返回path規範化的絕對路徑
os.path.split(path)  將path分割成目錄和文件名二元組返回,它僅僅是以  "PATH"  中最後一個  '/'  做爲分隔符,分隔後,將索引爲 0 的視爲目錄(路徑),將索引爲 1 的視爲文件名
os.path.dirname(path)  返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path)  返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path)  若是path存在,返回 True ;若是path不存在,返回 False
os.path.isabs(path)  若是path是絕對路徑,返回 True
os.path.isfile(path)  若是path是一個存在的文件,返回 True 。不然返回 False
os.path.isdir(path)  若是path是一個存在的目錄,則返回 True 。不然返回 False
os.path.join(path1[, path2[, ...]])  將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)  返回path所指向的文件或者目錄的最後存取時間
os.path.getmtime(path)  返回path所指向的文件或者目錄的最後修改時間

os.path.join示範

1
2
3
4
5
6
>>> os.path.join( 'c:\\', ' csv ', ' test.csv') 
'c:\\csv\\test.csv' 
>>> os.path.join( 'windows\temp' 'c:\\', ' csv ', ' test.csv') 
'c:\\csv\\test.csv' 
>>> os.path.join( '/home/aa' , '/home/aa/bb' , '/home/aa/bb/c'
'/home/aa/bb/c'

 

 

  1. time和datetime(http://www.jb51.net/article/49326.htm)

 

在Python中,一般有這幾種方式來表示時間:1)時間戳 2)格式化的時間字符串 3)元組(struct_time)共九個元素。因爲Python的time模塊實現主要調用C庫,因此各個平臺可能有所不一樣。


UTC(Coordinated Universal Time,世界協調時)亦即格林威治天文時間,世界標準時間。在中國爲UTC+8。DST(Daylight Saving Time)即夏令時。

 

時間戳(timestamp)的方式:一般來講,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。咱們運行「type(time.time())」,返回的是float類型。返回時間戳方式的函數主要有time(),clock()等。

 

元組(struct_time)方式:struct_time元組共有9個元素,返回struct_time的函數主要有gmtime(),localtime(),strptime()。下面列出這種方式元組中的幾個元素:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#_*_coding:utf-8_*_
import  time
 
 
# print(time.clock()) #返回處理器時間,3.3開始已廢棄 , 改爲了time.process_time()測量處理器運算時間,不包括sleep時間,不穩定,mac上測不出來
# print(time.altzone)  #返回與utc時間的時間差,以秒計算\
# print(time.asctime()) #返回時間格式"Fri Aug 19 11:14:16 2016",
# print(time.localtime()) #返回本地時間 的struct time對象格式
# print(time.gmtime(time.time()-800000)) #返回utc時間的struc時間對象格式
 
# print(time.asctime(time.localtime())) #返回時間格式"Fri Aug 19 11:14:16 2016",
#print(time.ctime()) #返回Fri Aug 19 12:38:29 2016 格式, 同上
 
 
 
# 日期字符串 轉成  時間戳
# string_2_struct = time.strptime("2016/05/22","%Y/%m/%d") #將 日期字符串 轉成 struct時間對象格式
# print(string_2_struct)
# #
# struct_2_stamp = time.mktime(string_2_struct) #將struct時間對象轉成時間戳
# print(struct_2_stamp)
 
 
 
#將時間戳轉爲字符串格式
# print(time.gmtime(time.time()-86640)) #將utc時間戳轉換成struct_time格式
# print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #將utc struct_time格式轉成指定的字符串格式
 
#時間加減
import  datetime
 
# print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925
#print(datetime.date.fromtimestamp(time.time()) )  # 時間戳直接轉成日期格式 2016-08-19
# print(datetime.datetime.now() )
# print(datetime.datetime.now() + datetime.timedelta(3)) #當前時間+3天
# print(datetime.datetime.now() + datetime.timedelta(-3)) #當前時間-3天
# print(datetime.datetime.now() + datetime.timedelta(hours=3)) #當前時間+3小時
# print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #當前時間+30分
 
 
#
# c_time  = datetime.datetime.now()
# print(c_time.replace(minute=3,hour=2)) #時間替換

格式參照

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
% a    本地(locale)簡化星期名稱    
% A    本地完整星期名稱    
% b    本地簡化月份名稱    
% B    本地完整月份名稱    
% c    本地相應的日期和時間表示    
% d    一個月中的第幾天( 01  -  31 )    
% H    一天中的第幾個小時( 24 小時制, 00  -  23 )    
% I    第幾個小時( 12 小時制, 01  -  12 )    
% j    一年中的第幾天( 001  -  366 )    
% m    月份( 01  -  12 )    
% M    分鐘數( 00  -  59 )    
% p    本地am或者pm的相應符    一    
% S    秒( 01  -  61 )    二    
% U    一年中的星期數。( 00  -  53 星期天是一個星期的開始。)第一個星期天以前的全部天數都放在第 0 周。    三    
% w    一個星期中的第幾天( 0  -  6 0 是星期天)    三    
% W    和 % U基本相同,不一樣的是 % W以星期一爲一個星期的開始。    
% x    本地相應日期    
% X    本地相應時間    
% y    去掉世紀的年份( 00  -  99 )    
% Y    完整的年份    
% Z    時區的名字(若是不存在爲空字符)    
% %     % ’字符

 時間關係轉換

wKioL1e28cPBlYGaAAGLKN2Vq_c463.jpg-wh_50

 

更多點擊這裏

2.random模塊

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python
#_*_encoding: utf-8_*_
import  random
print  (random.random())   #0.6445010863311293  
#random.random()用於生成一個0到1的隨機符點數: 0 <= n < 1.0
print  (random.randint( 1 , 7 ))  #4
#random.randint()的函數原型爲:random.randint(a, b),用於生成一個指定範圍內的整數。
# 其中參數a是下限,參數b是上限,生成的隨機數n: a <= n <= b
print  (random.randrange( 1 , 10 ))  #5
#random.randrange的函數原型爲:random.randrange([start], stop[, step]),
# 從指定範圍內,按指定基數遞增的集合中 獲取一個隨機數。如:random.randrange(10, 100, 2),
# 結果至關於從[10, 12, 14, 16, ... 96, 98]序列中獲取一個隨機數。
# random.randrange(10, 100, 2)在結果上與 random.choice(range(10, 100, 2) 等效。
print (random.choice( 'liukuni' ))  #i
#random.choice從序列中獲取一個隨機元素。
# 其函數原型爲:random.choice(sequence)。參數sequence表示一個有序類型。
# 這裏要說明一下:sequence在python不是一種特定的類型,而是泛指一系列的類型。
# list, tuple, 字符串都屬於sequence。有關sequence能夠查看python手冊數據模型這一章。
# 下面是使用choice的一些例子:
print (random.choice( "學習Python" )) #學
print (random.choice([ "JGood" , "is" , "a" , "handsome" , "boy" ]))   #List
print (random.choice(( "Tuple" , "List" , "Dict" )))    #List
print (random.sample([ 1 , 2 , 3 , 4 , 5 ], 3 ))     #[1, 2, 5]
#random.sample的函數原型爲:random.sample(sequence, k),從指定序列中隨機獲取指定長度的片段。sample函數不會修改原有序列。

 

實際應用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/env python
# encoding: utf-8
import  random
import  string
#隨機整數:
print ( random.randint( 0 , 99 ))   #70
 
#隨機選取0到100間的偶數:
print (random.randrange( 0 101 2 ))  #4
 
#隨機浮點數:
print ( random.random())  #0.2746445568079129
print (random.uniform( 1 10 ))  #9.887001463194844
 
#隨機字符:
print (random.choice( 'abcdefg&#%^*f' )) #f
 
#多個字符中選取特定數量的字符:
print (random.sample( 'abcdefghij' , 3 ))  #['f', 'h', 'd']
 
#隨機選取字符串:
print ( random.choice ( [ 'apple' 'pear' 'peach' 'orange' 'lemon' ] ))  #apple
#洗牌#
items  =  [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ]
print (items)  #[1, 2, 3, 4, 5, 6, 7]
random.shuffle(items)
print (items)  #[1, 4, 7, 2, 5, 3, 6]

生成隨機驗證碼:

1
2
3
4
5
6
7
8
9
10
import  random
checkcode  =  ''
for  in  range ( 4 ):
     current  =  random.randrange( 0 , 4 )
     if  current ! =  i:
         temp  =  chr (random.randint( 65 , 90 ))
     else :
         temp  =  random.randint( 0 , 9 )
     checkcode  + =  str (temp)
print  (checkcode)

 

3.os模塊

提供對操做系統進行調用的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑
os.chdir( "dirname" )  改變當前腳本工做目錄;至關於shell下cd
os.curdir  返回當前目錄: ( '.' )
os.pardir  獲取當前目錄的父目錄字符串名:( '..' )
os.makedirs( 'dirname1/dirname2' )    可生成多層遞歸目錄
os.removedirs( 'dirname1' )    若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir( 'dirname' )    生成單級目錄;至關於shell中mkdir dirname
os.rmdir( 'dirname' )    刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir( 'dirname' )    列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.remove()  刪除一個文件
os.rename( "oldname" , "newname" )  重命名文件 / 目錄
os.stat( 'path/filename' )  獲取文件 / 目錄信息
os.sep    輸出操做系統特定的路徑分隔符,win下爲 "\\",Linux下爲" / "
os.linesep    輸出當前平臺使用的行終止符,win下爲 "\t\n" ,Linux下爲 "\n"
os.pathsep    輸出用於分割文件路徑的字符串
os.name    輸出字符串指示當前使用平臺。win - > 'nt' ; Linux - > 'posix'
os.system( "bash command" )  運行shell命令,直接顯示
os.environ  獲取系統環境變量
os.path.abspath(path)  返回path規範化的絕對路徑
os.path.split(path)  將path分割成目錄和文件名二元組返回
os.path.dirname(path)  返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path)  返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path)  若是path存在,返回 True ;若是path不存在,返回 False
os.path.isabs(path)  若是path是絕對路徑,返回 True
os.path.isfile(path)  若是path是一個存在的文件,返回 True 。不然返回 False
os.path.isdir(path)  若是path是一個存在的目錄,則返回 True 。不然返回 False
os.path.join(path1[, path2[, ...]])  將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)  返回path所指向的文件或者目錄的最後存取時間
os.path.getmtime(path)  返回path所指向的文件或者目錄的最後修改時間

更多點擊這裏

print os.path.getatime("d:\\new")  #最後訪問時間
print os.path.getmtime("d:\\new") #最後修改路徑時間
print os.path.getctime("d:\\new")  #建立時間

4.sys模塊

1
2
3
4
5
6
7
8
sys.argv           命令行參數 List ,第一個元素是程序自己路徑
sys.exit(n)        退出程序,正常退出時exit( 0 )
sys.version        獲取Python解釋程序的版本信息
sys.maxint         最大的 Int
sys.path           返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform       返回操做系統平臺名稱
sys.stdout.write( 'please:' )
val  =  sys.stdin.readline()[: - 1 ]

 

5.shutil模塊

參考http://www.cnblogs.com/wupeiqi/articles/4963027.html 

 

6.json和pickle模塊

 

用於序列化的兩個模塊

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

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

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

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

wKioL1e29DbjpR--AABUpCNKHV0613.png-wh_50

 

7. shelve模塊

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

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

 

 

本節大綱:

  1. 模塊介紹
  2. time &datetime模塊
  3. random
  4. os
  5. sys
  6. shutil
  7. json & picle
  8. shelve
  9. xml處理
  10. yaml處理
  11. configparser
  12. hashlib
  13. subprocess
  14. logging模塊
  15. re正則表達式

 

 

模塊,用一砣代碼實現了某個功能的代碼集合。 

相似於函數式編程和麪向過程編程,函數式編程則完成一個功能,其餘代碼用來調用便可,提供了代碼的重用性和代碼間的耦合。而對於一個複雜的功能來,可能須要多個函數才能完成(函數又能夠在不一樣的.py文件中),n個 .py 文件組成的代碼集合就稱爲模塊。

如:os 是系統相關的模塊;file是文件操做相關的模塊

模塊分爲三種:

  • 自定義模塊
  • 內置標準模塊(又稱標準庫)
  • 開源模塊

自定義模塊 和開源模塊的使用參考 http://www.cnblogs.com/wupeiqi/articles/4963027.html 

 

 

time & datetime模塊

 1  1 #_*_coding:utf-8_*_
 2  2 __author__ = 'Alex Li'
 3  3 
 4  4 import time
 5  5 
 6  6 
 7  7 # print(time.clock()) #返回處理器時間,3.3開始已廢棄 , 改爲了time.process_time()測量處理器運算時間,不包括sleep時間,不穩定,mac上測不出來
 8  8 # print(time.altzone)  #返回與utc時間的時間差,以秒計算\
 9  9 # print(time.asctime()) #返回時間格式"Fri Aug 19 11:14:16 2016",
10 10 # print(time.localtime()) #返回本地時間 的struct time對象格式
11 11 # print(time.gmtime(time.time()-800000)) #返回utc時間的struc時間對象格式
12 12 
13 13 # print(time.asctime(time.localtime())) #返回時間格式"Fri Aug 19 11:14:16 2016",
14 14 #print(time.ctime()) #返回Fri Aug 19 12:38:29 2016 格式, 同上
15 15 
16 16 
17 17 
18 18 # 日期字符串 轉成  時間戳
19 19 # string_2_struct = time.strptime("2016/05/22","%Y/%m/%d") #將 日期字符串 轉成 struct時間對象格式
20 20 # print(string_2_struct)
21 21 # #
22 22 # struct_2_stamp = time.mktime(string_2_struct) #將struct時間對象轉成時間戳
23 23 # print(struct_2_stamp)
24 24 
25 25 
26 26 
27 27 #將時間戳轉爲字符串格式
28 28 # print(time.gmtime(time.time()-86640)) #將utc時間戳轉換成struct_time格式
29 29 # print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #將utc struct_time格式轉成指定的字符串格式
30 30 
31 31 
32 32 
33 33 
34 34 
35 35 #時間加減
36 36 import datetime
37 37 
38 38 # print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925
39 39 #print(datetime.date.fromtimestamp(time.time()) )  # 時間戳直接轉成日期格式 2016-08-19
40 40 # print(datetime.datetime.now() )
41 41 # print(datetime.datetime.now() + datetime.timedelta(3)) #當前時間+3天
42 42 # print(datetime.datetime.now() + datetime.timedelta(-3)) #當前時間-3天
43 43 # print(datetime.datetime.now() + datetime.timedelta(hours=3)) #當前時間+3小時
44 44 # print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #當前時間+30分
45 45 
46 46 
47 47 #
48 48 # c_time  = datetime.datetime.now()
49 49 # print(c_time.replace(minute=3,hour=2)) #時間替換
View Code

 

 
Directive Meaning Notes
%a Locale’s abbreviated weekday name.  
%A Locale’s full weekday name.  
%b Locale’s abbreviated month name.  
%B Locale’s full month name.  
%c Locale’s appropriate date and time representation.  
%d Day of the month as a decimal number [01,31].  
%H Hour (24-hour clock) as a decimal number [00,23].  
%I Hour (12-hour clock) as a decimal number [01,12].  
%j Day of the year as a decimal number [001,366].  
%m Month as a decimal number [01,12].  
%M Minute as a decimal number [00,59].  
%p Locale’s equivalent of either AM or PM. (1)
%S Second as a decimal number [00,61]. (2)
%U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3)
%w Weekday as a decimal number [0(Sunday),6].  
%W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3)
%x Locale’s appropriate date representation.  
%X Locale’s appropriate time representation.  
%y Year without century as a decimal number [00,99].  
%Y Year with century as a decimal number.  
%z Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].  
%Z Time zone name (no characters if no time zone exists).  
%% A literal '%' character.

 

 

 

random模塊

隨機數

1
2
3
4
mport random
print  random.random()
print  random.randint( 1 , 2 )
print  random.randrange( 1 , 10 )

生成隨機驗證碼

1
2
3
4
5
6
7
8
9
10
import  random
checkcode  =  ''
for  in  range ( 4 ):
     current  =  random.randrange( 0 , 4 )
     if  current ! =  i:
         temp  =  chr (random.randint( 65 , 90 ))
     else :
         temp  =  random.randint( 0 , 9 )
     checkcode  + =  str (temp)
print  checkcode

 

OS模塊  

提供對操做系統進行調用的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑
os.chdir( "dirname" )  改變當前腳本工做目錄;至關於shell下cd
os.curdir  返回當前目錄: ( '.' )
os.pardir  獲取當前目錄的父目錄字符串名:( '..' )
os.makedirs( 'dirname1/dirname2' )    可生成多層遞歸目錄
os.removedirs( 'dirname1' )    若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir( 'dirname' )    生成單級目錄;至關於shell中mkdir dirname
os.rmdir( 'dirname' )    刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir( 'dirname' )    列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.remove()  刪除一個文件
os.rename( "oldname" , "newname" )  重命名文件 / 目錄
os.stat( 'path/filename' )  獲取文件 / 目錄信息
os.sep    輸出操做系統特定的路徑分隔符,win下爲 "\\",Linux下爲" / "
os.linesep    輸出當前平臺使用的行終止符,win下爲 "\t\n" ,Linux下爲 "\n"
os.pathsep    輸出用於分割文件路徑的字符串
os.name    輸出字符串指示當前使用平臺。win - > 'nt' ; Linux - > 'posix'
os.system( "bash command" )  運行shell命令,直接顯示
os.environ  獲取系統環境變量
os.path.abspath(path)  返回path規範化的絕對路徑
os.path.split(path)  將path分割成目錄和文件名二元組返回
os.path.dirname(path)  返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path)  返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path)  若是path存在,返回 True ;若是path不存在,返回 False
os.path.isabs(path)  若是path是絕對路徑,返回 True
os.path.isfile(path)  若是path是一個存在的文件,返回 True 。不然返回 False
os.path.isdir(path)  若是path是一個存在的目錄,則返回 True 。不然返回 False
os.path.join(path1[, path2[, ...]])  將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)  返回path所指向的文件或者目錄的最後存取時間
os.path.getmtime(path)  返回path所指向的文件或者目錄的最後修改時間

更多猛擊這裏 

 

sys模塊

1
2
3
4
5
6
7
8
sys.argv           命令行參數 List ,第一個元素是程序自己路徑
sys.exit(n)        退出程序,正常退出時exit( 0 )
sys.version        獲取Python解釋程序的版本信息
sys.maxint         最大的 Int
sys.path           返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform       返回操做系統平臺名稱
sys.stdout.write( 'please:' )
val  =  sys.stdin.readline()[: - 1 ]

 

shutil 模塊

直接參考 http://www.cnblogs.com/wupeiqi/articles/4963027.html 

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

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)
遞歸的去拷貝文件

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' )

 

 1 import zipfile
 2 
 3 # 壓縮
 4 z = zipfile.ZipFile('laxi.zip', 'w')
 5 z.write('a.log')
 6 z.write('data.data')
 7 z.close()
 8 
 9 # 解壓
10 z = zipfile.ZipFile('laxi.zip', 'r')
11 z.extractall()
12 z.close()
13 複製代碼
zipfile 壓縮解壓
 1 import tarfile
 2 
 3 # 壓縮
 4 tar = tarfile.open('your.tar','w')
 5 tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip')
 6 tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip')
 7 tar.close()
 8 
 9 # 解壓
10 tar = tarfile.open('your.tar','r')
11 tar.extractall()  # 可設置解壓地址
12 tar.close()
tarfile 壓縮解壓

 

json & pickle 模塊

用於序列化的兩個模塊

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

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

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

 

shelve 模塊

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

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

  

xml處理模塊

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<? 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   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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  in  child:
         print (i.tag,i.text)
 
#只遍歷year 節點
for  node  in  root. iter ( 'year' ):
     print (node.tag,node.text)

修改和刪除xml文檔內容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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文檔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)  #打印生成的格式

 

PyYAML模塊

Python也能夠很容易的處理ymal文檔格式,只不過須要安裝一個模塊,參考文檔:http://pyyaml.org/wiki/PyYAMLDocumentation 

 

ConfigParser模塊

用於生成和修改常見配置文檔,當前模塊的名稱在 python 3.x 版本中變動爲 configparser。

來看一個好多軟件的常見文檔格式以下

1
2
3
4
5
6
7
8
9
10
11
12
[DEFAULT]
ServerAliveInterval  =  45
Compression  =  yes
CompressionLevel  =  9
ForwardX11  =  yes
 
[bitbucket.org]
User  =  hg
 
[topsecret.server.com]
Port  =  50022
ForwardX11  =  no

若是想用python生成一個這樣的文檔怎麼作呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import  configparser
 
config  =  configparser.ConfigParser()
config[ "DEFAULT" =  { 'ServerAliveInterval' '45' ,
                       'Compression' 'yes' ,
                      'CompressionLevel' '9' }
 
config[ 'bitbucket.org' =  {}
config[ 'bitbucket.org' ][ 'User' =  'hg'
config[ 'topsecret.server.com' =  {}
topsecret  =  config[ 'topsecret.server.com' ]
topsecret[ 'Host Port' =  '50022'      # mutates the parser
topsecret[ 'ForwardX11' =  'no'   # same here
config[ 'DEFAULT' ][ 'ForwardX11' =  'yes'
with  open ( 'example.ini' 'w' ) as configfile:
    config.write(configfile)

  

寫完了還能夠再讀出來哈。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
>>>  import  configparser
>>> config  =  configparser.ConfigParser()
>>> config.sections()
[]
>>> config.read( 'example.ini' )
[ 'example.ini' ]
>>> config.sections()
[ 'bitbucket.org' 'topsecret.server.com' ]
>>>  'bitbucket.org'  in  config
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)
...
user
compressionlevel
serveraliveinterval
compression
forwardx11
>>> config[ 'bitbucket.org' ][ 'ForwardX11' ]
'yes'

configparser增刪改查語法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
[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"))

  

hashlib模塊  

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import  hashlib
 
=  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())

還不夠吊?python 還有一個 hmac 模塊,它內部對咱們建立 key 和 內容 再進行處理而後再加密

散列消息鑑別碼,簡稱HMAC,是一種基於消息鑑別碼MAC(Message Authentication Code)的鑑別機制。使用HMAC時,消息通信的雙方,經過驗證消息中加入的鑑別密鑰K來鑑別消息的真僞;

通常用於網絡通訊中消息加密,前提是雙方先要約定好key,就像接頭暗號同樣,而後消息發送把用key把消息加密,接收方用key + 消息明文再加密,拿加密後的值 跟 發送者的相對比是否相等,這樣就能驗證消息的真實性,及發送者的合法性了。

 

1
2
3
import  hmac
=  hmac.new(b '天王蓋地虎' , b '寶塔鎮河妖' )
print  h.hexdigest()

更多關於md5,sha1,sha256等介紹的文章看這裏https://www.tbs-certificates.co.uk/FAQ/en/sha256.html 

  

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:

os.system os.spawn*

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.

(args*stdin=Noneinput=Nonestdout=Nonestderr=Noneshell=Falsetimeout=Nonecheck=False)subprocess.run

Run the command described by args. Wait for command to complete, then return a CompletedProcess instance.

The arguments shown above are merely the most common ones, described below in Frequently Used Arguments (hence the use of keyword-only notation in the abbreviated signature). The full function signature is largely the same as that of the Popen constructor - apart from timeoutinput and check, all the arguments to this function are passed through to that interface.

This does not capture stdout or stderr by default. To do so, pass PIPE for the stdout and/or stderr arguments.

The timeout argument is passed to Popen.communicate(). If the timeout expires, the child process will be killed and waited for. The TimeoutExpired exception will be re-raised after the child process has terminated.

The input argument is passed to Popen.communicate() and thus to the subprocess’s stdin. If used it must be a byte sequence, or a string if universal_newlines=True. When used, the internal Popen object is automatically created withstdin=PIPE, and the stdin argument may not be used as well.

If check is True, and the process exits with a non-zero exit code, a CalledProcessError exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.

經常使用subprocess方法示例

#執行命令,返回命令執行狀態 , 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'

#上面那些方法,底層都是封裝的subprocess.Popen
poll()
Check if child process has terminated. Returns returncode

wait()
Wait for child process to terminate. Returns returncode attribute.


terminate() 殺掉所啓動進程
communicate() 等待任務結束

stdin 標準輸入

stdout 標準輸出

stderr 標準錯誤

pid
The process ID of the child process.

#例子
>>> p = subprocess.Popen("df -h|grep disk",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
>>> p.stdout.read()
b'/dev/disk1 465Gi 64Gi 400Gi 14% 16901472 104938142 14% /\n'

 

 

 

1
2
3
4
5
6
7
8
9
10
11
>>> subprocess.run([ "ls" "-l" ])   # doesn't capture output
CompletedProcess(args = [ 'ls' '-l' ], returncode = 0 )
 
>>> subprocess.run( "exit 1" , shell = True , check = True )
Traceback (most recent call last):
   ...
subprocess.CalledProcessError: Command  'exit 1'  returned non - zero exit status  1
 
>>> subprocess.run([ "ls" "-l" "/dev/null" ], stdout = subprocess.PIPE)
CompletedProcess(args = [ 'ls' '-l' '/dev/null' ], returncode = 0 ,
stdout = b 'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n' )

 

調用subprocess.run(...)是推薦的經常使用方法,在大多數狀況下能知足需求,但若是你可能須要進行一些複雜的與系統的交互的話,你還能夠用subprocess.Popen(),語法以下:

1
2
=  subprocess.Popen( "find / -size +1000000 -exec ls -shl {} \;" ,shell = True ,stdout = subprocess.PIPE)
print (p.stdout.read())

可用參數:

  • args:shell命令,能夠是字符串或者序列類型(如:list,元組)
  • bufsize:指定緩衝。0 無緩衝,1 行緩衝,其餘 緩衝區大小,負值 系統緩衝
  • stdin, stdout, stderr:分別表示程序的標準輸入、輸出、錯誤句柄
  • preexec_fn:只在Unix平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行以前被調用
  • close_sfs:在windows平臺下,若是close_fds被設置爲True,則新建立的子進程將不會繼承父進程的輸入、輸出、錯誤管道。
    因此不能將close_fds設置爲True同時重定向子進程的標準輸入、輸出與錯誤(stdin, stdout, stderr)。
  • shell:同上
  • cwd:用於設置子進程的當前目錄
  • env:用於指定子進程的環境變量。若是env = None,子進程的環境變量將從父進程中繼承。
  • universal_newlines:不一樣系統的換行符不一樣,True -> 贊成使用 \n
  • startupinfo與createionflags只在windows下有效
    將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等

終端輸入的命令分爲兩種:

  • 輸入便可獲得輸出,如:ifconfig
  • 輸入進行某環境,依賴再輸入,如:python

須要交互的命令示例

1
2
3
4
5
6
7
8
9
10
import  subprocess
 
obj  =  subprocess.Popen([ "python" ], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
obj.stdin.write( 'print 1 \n ' )
obj.stdin.write( 'print 2 \n ' )
obj.stdin.write( 'print 3 \n ' )
obj.stdin.write( 'print 4 \n ' )
 
out_error_list  =  obj.communicate(timeout = 10 )
print  out_error_list

subprocess實現sudo 自動輸入密碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import  subprocess
 
def  mypass():
     mypass  =  '123'  #or get the password from anywhere
     return  mypass
 
echo  =  subprocess.Popen([ 'echo' ,mypass()],
                         stdout = subprocess.PIPE,
                         )
 
sudo  =  subprocess.Popen([ 'sudo' , '-S' , 'iptables' , '-L' ],
                         stdin = echo.stdout,
                         stdout = subprocess.PIPE,
                         )
 
end_of_pipe  =  sudo.stdout
 
print  "Password ok \n Iptables Chains %s"  %  end_of_pipe.read()

  

  

logging模塊  

不少程序都有記錄日誌的需求,而且日誌中包含的信息即有正常的程序訪問日誌,還可能有錯誤、警告等信息輸出,python的logging模塊提供了標準的日誌接口,你能夠經過它存儲各類格式的日誌,logging的日誌能夠分爲 debug()info()warning()error() and critical() 5個級別,下面咱們看一下怎麼用。

最簡單用法

1
2
3
4
5
6
7
8
import  logging
 
logging.warning( "user [alex] attempted wrong password more than 3 times" )
logging.critical( "server is down" )
 
#輸出
WARNING:root:user [alex] attempted wrong password more than  3  times
CRITICAL:root:server  is  down

看一下這幾個日誌級別分別表明什麼意思

Level When it’s used
DEBUG Detailed information, typically of interest only when diagnosing problems.
INFO Confirmation that things are working as expected.
WARNING An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected.
ERROR Due to a more serious problem, the software has not been able to perform some function.
CRITICAL A serious error, indicating that the program itself may be unable to continue running.

  

若是想把日誌寫到文件裏,也很簡單

1
2
3
4
5
6
import  logging
 
logging.basicConfig(filename = 'example.log' ,level = logging.INFO)
logging.debug( 'This message should go to the log file' )
logging.info( 'So should this' )
logging.warning( 'And this, too' )

其中下面這句中的level=loggin.INFO意思是,把日誌紀錄級別設置爲INFO,也就是說,只有比日誌是INFO或比INFO級別更高的日誌纔會被紀錄到文件裏,在這個例子, 第一條日誌是不會被紀錄的,若是但願紀錄debug的日誌,那把日誌級別改爲DEBUG就好了。

1
logging.basicConfig(filename = 'example.log' ,level = logging.INFO)

感受上面的日誌格式忘記加上時間啦,日誌不知道時間怎麼行呢,下面就來加上!

1
2
3
4
5
6
import  logging
logging.basicConfig( format = '%(asctime)s %(message)s' , datefmt = '%m/%d/%Y %I:%M:%S %p' )
logging.warning( 'is when this event was logged.' )
 
#輸出
12 / 12 / 2010  11 : 46 : 36  AM  is  when this event was logged.

日誌格式

%(name)s

Logger的名字

%(levelno)s

數字形式的日誌級別

%(levelname)s

文本形式的日誌級別

%(pathname)s

調用日誌輸出函數的模塊的完整路徑名,可能沒有

%(filename)s

調用日誌輸出函數的模塊的文件名

%(module)s

調用日誌輸出函數的模塊名

%(funcName)s

調用日誌輸出函數的函數名

%(lineno)d

調用日誌輸出函數的語句所在的代碼行

%(created)f

當前時間,用UNIX標準的表示時間的浮 點數表示

%(relativeCreated)d

輸出日誌信息時的,自Logger建立以 來的毫秒數

%(asctime)s

字符串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒

%(thread)d

線程ID。可能沒有

%(threadName)s

線程名。可能沒有

%(process)d

進程ID。可能沒有

%(message)s

用戶輸出的消息

 

 

 

  

若是想同時把log打印在屏幕和文件日誌裏,就須要瞭解一點複雜的知識 了


Python 使用logging模塊記錄日誌涉及四個主要類,使用官方文檔中的歸納最爲合適:

logger提供了應用程序能夠直接使用的接口;

handler將(logger建立的)日誌記錄發送到合適的目的輸出;

filter提供了細度設備來決定輸出哪條日誌記錄;

formatter決定日誌記錄的最終輸出格式。

logger
每一個程序在輸出信息以前都要得到一個Logger。Logger一般對應了程序的模塊名,好比聊天工具的圖形界面模塊能夠這樣得到它的Logger:
LOG=logging.getLogger(」chat.gui」)
而核心模塊能夠這樣:
LOG=logging.getLogger(」chat.kernel」)

Logger.setLevel(lel):指定最低的日誌級別,低於lel的級別將被忽略。debug是最低的內置級別,critical爲最高
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或刪除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增長或刪除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():能夠設置的日誌級別

 

handler

handler對象負責發送相關的信息到指定目的地。Python的日誌系統有多種Handler可使用。有些Handler能夠把信息輸出到控制檯,有些Logger能夠把信息輸出到文件,還有些 Handler能夠把信息發送到網絡上。若是以爲不夠用,還能夠編寫本身的Handler。能夠經過addHandler()方法添加多個多handler
Handler.setLevel(lel):指定被處理的信息級別,低於lel級別的信息將被忽略
Handler.setFormatter():給這個handler選擇一個格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或刪除一個filter對象


每一個Logger能夠附加多個Handler。接下來咱們就來介紹一些經常使用的Handler:
1) logging.StreamHandler
使用這個Handler能夠向相似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息。它的構造函數是:
StreamHandler([strm])
其中strm參數是一個文件對象。默認是sys.stderr


2) logging.FileHandler
和StreamHandler相似,用於向一個文件輸出日誌信息。不過FileHandler會幫你打開這個文件。它的構造函數是:
FileHandler(filename[,mode])
filename是文件名,必須指定一個文件名。
mode是文件的打開方式。參見Python內置函數open()的用法。默認是’a',即添加到文件末尾。

3) logging.handlers.RotatingFileHandler
這個Handler相似於上面的FileHandler,可是它能夠管理文件大小。當文件達到必定大小以後,它會自動將當前日誌文件更名,而後建立 一個新的同名日誌文件繼續輸出。好比日誌文件是chat.log。當chat.log達到指定的大小以後,RotatingFileHandler自動把 文件更名爲chat.log.1。不過,若是chat.log.1已經存在,會先把chat.log.1重命名爲chat.log.2。。。最後從新建立 chat.log,繼續輸出日誌信息。它的構造函數是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode兩個參數和FileHandler同樣。
maxBytes用於指定日誌文件的最大文件大小。若是maxBytes爲0,意味着日誌文件能夠無限大,這時上面描述的重命名過程就不會發生。
backupCount用於指定保留的備份文件的個數。好比,若是指定爲2,當上面描述的重命名過程發生時,原有的chat.log.2並不會被改名,而是被刪除。


4) logging.handlers.TimedRotatingFileHandler
這個Handler和RotatingFileHandler相似,不過,它沒有經過判斷文件大小來決定什麼時候從新建立日誌文件,而是間隔必定時間就 自動建立新的日誌文件。重命名的過程與RotatingFileHandler相似,不過新的文件不是附加數字,而是當前時間。它的構造函數是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename參數和backupCount參數和RotatingFileHandler具備相同的意義。
interval是時間間隔。
when參數是一個字符串。表示時間間隔的單位,不區分大小寫。它有如下取值:
S 秒
M 分
H 小時
D 天
W 每星期(interval==0時表明星期一)
midnight 天天凌晨

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import  logging
 
#create logger
logger  =  logging.getLogger( 'TEST-LOG' )
logger.setLevel(logging.DEBUG)
 
 
# create console handler and set level to debug
ch  =  logging.StreamHandler()
ch.setLevel(logging.DEBUG)
 
# create file handler and set level to warning
fh  =  logging.FileHandler( "access.log" )
fh.setLevel(logging.WARNING)
# create formatter
formatter  =  logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' )
 
# add formatter to ch and fh
ch.setFormatter(formatter)
fh.setFormatter(formatter)
 
# add ch and fh to logger
logger.addHandler(ch)
logger.addHandler(fh)
 
# 'application' code
logger.debug( 'debug message' )
logger.info( 'info message' )
logger.warn( 'warn message' )
logger.error( 'error message' )
logger.critical( 'critical message' )

  

 

文件自動截斷例子

 1 import logging
 2 
 3 from logging import handlers
 4 
 5 logger = logging.getLogger(__name__)
 6 
 7 log_file = "timelog.log"
 8 #fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)
 9 fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3)
10 
11 
12 formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')
13 
14 fh.setFormatter(formatter)
15 
16 logger.addHandler(fh)
17 
18 
19 logger.warning("test1")
20 logger.warning("test12")
21 logger.warning("test13")
22 logger.warning("test14")
23 複製代碼
View Code

 

 

 

re模塊   

經常使用正則表達式符號

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
'.'      默認匹配除\n以外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
'^'      匹配字符開頭,若指定flags MULTILINE,這種也能夠匹配上(r "^a" , "\nabc\neee" ,flags = re.MULTILINE)
'$'      匹配字符結尾,或e.search( "foo$" , "bfoo\nsdfsf" ,flags = re.MULTILINE).group()也能夠
'*'      匹配 * 號前的字符 0 次或屢次,re.findall( "ab*" , "cabb3abcbbac" )  結果爲[ 'abb' 'ab' 'a' ]
'+'      匹配前一個字符 1 次或屢次,re.findall( "ab+" , "ab+cd+abb+bba" ) 結果[ 'ab' 'abb' ]
'?'      匹配前一個字符 1 次或 0
'{m}'    匹配前一個字符m次
'{n,m}'  匹配前一個字符n到m次,re.findall( "ab{1,3}" , "abb abc abbcbbb" ) 結果 'abb' 'ab' 'abb' ]
'|'      匹配|左或|右的字符,re.search( "abc|ABC" , "ABCBabcCD" ).group() 結果 'ABC'
'(...)'  分組匹配,re.search( "(abc){2}a(123|456)c" "abcabca456c" ).group() 結果 abcabca456c
 
 
'\A'     只從字符開頭匹配,re.search( "\Aabc" , "alexabc" ) 是匹配不到的
'\Z'     匹配字符結尾,同$
'\d'     匹配數字 0 - 9
'\D'     匹配非數字
'\w'     匹配[A - Za - z0 - 9 ]
'\W'     匹配非[A - Za - z0 - 9 ]
's'      匹配空白字符、\t、\n、\r , re.search( "\s+" , "ab\tc1\n3" ).group() 結果  '\t'
 
'(?P<name>...)'  分組匹配 re.search( "(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})" , "371481199306143242" ).groupdict( "city" ) 結果{ 'province' '3714' 'city' '81' 'birthday' '1993' }

  

最經常使用的匹配語法

1
2
3
4
5
re.match 從頭開始匹配
re.search 匹配包含
re.findall 把全部匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符當作列表分隔符
re.sub      匹配字符並替換

反斜槓的困擾
與大多數編程語言相同,正則表達式裏使用"\"做爲轉義字符,這就可能形成反斜槓困擾。假如你須要匹配文本中的字符"\",那麼使用編程語言表示的正則表達式裏將須要4個反斜槓"\\\\":前兩個和後兩個分別用於在編程語言裏轉義成反斜槓,轉換成兩個反斜槓後再在正則表達式裏轉義成一個反斜槓。Python裏的原生字符串很好地解決了這個問題,這個例子中的正則表達式可使用r"\\"表示。一樣,匹配一個數字的"\\d"能夠寫成r"\d"。有了原生字符串,你不再用擔憂是否是漏寫了反斜槓,寫出來的表達式也更直觀。

 

僅需輕輕知道的幾個匹配模式

1
2
3
re.I(re.IGNORECASE): 忽略大小寫(括號內是完整寫法,下同)
M(MULTILINE): 多行模式,改變 '^' '$' 的行爲(參見上圖)
S(DOTALL): 點任意匹配模式,改變 '.' 的行爲
相關文章
相關標籤/搜索