day16

OS 模塊javascript

os模塊就是對操做系統進行操做,使用該模塊必須先導入模塊:import oshtml

  • getcwd() 獲取當前工做目錄(當前工做目錄默認都是當前文件所在的文件夾)
    result = os.getcwd()
    print(result)java

  • chdir()改變當前工做目錄
    os.chdir('/home/sy')
    result = os.getcwd()
    print(result)node

    open('02.txt','w')python

  • 操做時若是書寫完整的路徑則不須要考慮默認工做目錄的問題,按照實際書寫路徑操做
    open('/home/sy/下載/02.txt','w')linux

  • listdir() 獲取指定文件夾中全部內容的名稱列表
    result = os.listdir('/home/sy')
    print(result)git

  • mkdir() 建立文件夾
    os.mkdir('girls')
    os.mkdir('boys',0o777)github

  • makedirs() 遞歸建立文件夾
    os.makedirs('/home/sy/a/b/c/d')web

  • rmdir() 刪除空目錄
    os.rmdir('girls')算法

  • removedirs 遞歸刪除文件夾 必須都是空目錄
    os.removedirs('/home/sy/a/b/c/d')

  • rename() 文件或文件夾重命名
    os.rename('/home/sy/a','/home/sy/alibaba'
    os.rename('02.txt','002.txt')

  • stat() 獲取文件或者文件夾的信息
    result = os.stat('/home/sy/PycharmProject/Python3/10.27/01.py)
    print(result)

  • system() 執行系統命令(危險函數)
    result = os.system('ls -al') #獲取隱藏文件
    print(result)

環境變量
環境變量就是一些命令的集合
操做系統的環境變量就是操做系統在執行系統命令時搜索命令的目錄的集合

  • getenv() 獲取系統的環境變量
    result = os.getenv('PATH')
    print(result.split(':'))
  • putenv() 將一個目錄添加到環境變量中(臨時增長僅對當前腳本有效)
    os.putenv('PATH','/home/sy/下載')
    os.system('syls')
  • exit() 退出終端的命令
  • os模塊中的經常使用值
    curdir 表示當前文件夾 .表示當前文件夾 通常狀況下能夠省略
    print(os.curdir)
  • pardir 表示上一層文件夾 ..表示上一層文件夾 不可省略!
    print(os.pardir)
  • os.mkdir('../../../man')#相對路徑 從當前目錄開始查找
    os.mkdir('/home/sy/man1')#絕對路徑 從根目錄開始查找
  • name 獲取表明操做系統的名稱字符串
    print(os.name) #posix -> linux或者unix系統 nt -> window系統
  • sep 獲取系統路徑間隔符號 window ->  linux ->/
    print(os.sep)
  • extsep 獲取文件名稱和後綴之間的間隔符號 window & linux -> .
    print(os.extsep)
  • linesep 獲取操做系統的換行符號 window -> \r\n linux/unix -> \n
    print(repr(os.linesep))

導入os模塊 import os:

  • abspath() 將相對路徑轉化爲絕對路徑
    path = './boys'#相對
    result = os.path.abspath(path)
    print(result)

  • dirname() 獲取完整路徑當中的目錄部分 & basename()獲取完整路徑當中的主體部分
    path = '/home/sy/boys'
    result = os.path.dirname(path)
    print(result)

    result = os.path.basename(path)
    print(result)

  • split() 將一個完整的路徑切割成目錄部分和主體部分
    path = '/home/sy/boys'
    result = os.path.split(path)
    print(result)

  • join() 將2個路徑合併成一個
    var1 = '/home/sy'
    var2 = '000.py'
    result = os.path.join(var1,var2)
    print(result)

  • splitext() 將一個路徑切割成文件後綴和其餘兩個部分,主要用於獲取文件的後綴
    path = '/home/sy/000.py'
    result = os.path.splitext(path)
    print(result)

  • getsize() 獲取文件的大小
    path = '/home/sy/000.py'
    result = os.path.getsize(path)
    print(result)

  • isfile() 檢測是不是文件
    path = '/home/sy/000.py'
    result = os.path.isfile(path)
    print(result)

  • isdir() 檢測是不是文件夾
    result = os.path.isdir(path)
    print(result)

  • islink() 檢測是不是連接
    path = '/initrd.img.old'
    result = os.path.islink(path)
    print(result)

  • getctime() 獲取文件的建立時間 get create time
    getmtime() 獲取文件的修改時間 get modify time
    getatime() 獲取文件的訪問時間 get active time

import time

filepath = '/home/sy/下載/chls'

result = os.path.getctime(filepath)
print(time.ctime(result))

result = os.path.getmtime(filepath)
print(time.ctime(result))

result = os.path.getatime(filepath)
print(time.ctime(result))

  • exists() 檢測某個路徑是否真實存在
    filepath = '/home/sy/下載/chls'
    result = os.path.exists(filepath)
    print(result)
  • isabs() 檢測一個路徑是不是絕對路徑
    path = '/boys'
    result = os.path.isabs(path)
    print(result)
  • samefile() 檢測2個路徑是不是同一個文件
    path1 = '/home/sy/下載/001'
    path2 = '../../../下載/001'
    result = os.path.samefile(path1,path2)
    print(result)
  • os.environ 用於獲取和設置系統環境變量的內置值
    import os
    獲取系統環境變量 getenv() 效果
    print(os.environ['PATH'])
  • 設置系統環境變量 putenv()
    os.environ['PATH'] += ':/home/sy/下載'
    os.system('chls')

os 經常使用方法:

  • os.remove(‘path/filename’) 刪除文件
  • os.rename(oldname, newname) 重命名文件
  • os.walk() 生成目錄樹下的全部文件名
  • os.chdir('dirname') 改變目錄
  • os.mkdir/makedirs('dirname')建立目錄/多層目錄
  • os.rmdir/removedirs('dirname') 刪除目錄/多層目錄
  • os.listdir('dirname') 列出指定目錄的文件
  • os.getcwd() 取得當前工做目錄
  • os.chmod() 改變目錄權限
  • os.path.basename(‘path/filename’) 去掉目錄路徑,返回文件名
  • os.path.dirname(‘path/filename’) 去掉文件名,返回目錄路徑
  • os.path.join(path1[,path2[,...]]) 將分離的各部分組合成一個路徑名
  • os.path.split('path') 返回( dirname(), basename())元組
  • os.path.splitext() 返回 (filename, extension) 元組
  • os.path.getatime\ctime\mtime 分別返回最近訪問、建立、修改時間
  • os.path.getsize() 返回文件大小
  • os.path.exists() 是否存在
  • os.path.isabs() 是否爲絕對路徑
  • os.path.isdir() 是否爲目錄
  • os.path.isfile() 是否爲文件

sys模塊

  • sys.argv 命令行參數List,第一個元素是程序自己路徑
  • sys.modules.keys() 返回全部已經導入的模塊列表
  • sys.exc_info() 獲取當前正在處理的異常類,exc_type、exc_value、exc_traceback當前處理的異常詳細信息
  • sys.exit(n) 退出程序,正常退出時exit(0)
  • sys.hexversion 獲取Python解釋程序的版本值,16進制格式如:0x020403F0
  • sys.version 獲取Python解釋程序的版本信息
  • sys.maxint 最大的Int值
  • sys.maxunicode 最大的Unicode值
  • sys.modules 返回系統導入的模塊字段,key是模塊名,value是模塊
  • sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
  • sys.platform 返回操做系統平臺名稱
  • sys.stdout 標準輸出
  • sys.stdin 標準輸入
  • sys.stderr 錯誤輸出
  • sys.exc_clear() 用來清除當前線程所出現的當前的或最近的錯誤信息
  • sys.exec_prefix 返回平臺獨立的python文件安裝的位置
  • sys.byteorder 本地字節規則的指示器,big-endian平臺的值是'big',little-endian平臺的值是'little'
  • sys.copyright 記錄python版權相關的東西
  • sys.api_version 解釋器的C的API版本

time模塊

time模塊中時間表現的格式主要有三種:

  a、timestamp時間戳,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量

  b、struct_time時間元組,共有九個元素組。

  c、format time 格式化時間,已格式化的結構使時間更具可讀性。包括自定義格式和固定格式。

一、時間格式轉換圖:

img

二、主要time生成方法和time格式轉換方法實例:

--sleep:休眠指定的秒數(能夠是小數)

import time
print("開始")
time.sleep(5)
print("結束")
#若是在pycharm中輸入這段代碼,從開始到結束,中間會停留5秒,sleep後面的括號裏面填的數字就是秒數

--time:獲取時間戳

import time
t = time.time()
print(t)
#這段代碼是獲取時間戳(從1970-01-01 00:00:00到你輸入代碼運行時的秒數)

--localtime:將時間戳轉換爲對象

import time
local_time = time.localtime()
 print(local_time)
#會打印出此時此刻的年月日時分秒
 print(local_time.tm_year)
#指定輸出對應的年份
 print(local_time[0])
#也能夠指定下標輸出年份

mktime:根據年月日等信息轉換爲時間戳

import time
new_time = time.mktime((2099, 9, 9, 10, 10, 10, 1, 212, 0))
#上面括號裏面是填寫自定義的時間,要寫夠9個數字
print(new_time)
#輸出的時1970-01-01 00:00:00到自定義時間的秒數

gmtime:功能同localtime

import time
gt = time.gmtime()
print(gt)
#輸出當前時間的年月日時分秒

timezone:0時區到你所在的時區的相差秒數(/3600 = 小時)

import time
print(time.timezone/3600)
#我所在的是東8區,因此輸出的是-8.0

strftime:將time.struct_time對象格式化顯示

import time
local_time = time.localtime()
# 格式化顯示
print(time.strftime('%Y-%m-%d %H:%M:%S', local_time))
#規定輸出的格式

print(time.strftime('%D', local_time))
#\D是一種特定的顯示格式 月/日/年

#%Y:年(4位), %y:年(2位), %m:月, %d:日, %D:月/日/年, %H:時
#%M:分, %S:秒, %w:星期(1~7), %W:本週是今年的第幾周
# 特定的顯示格式
print(time.asctime())
#格式輸出當前的時間

format time結構化表示

格式 含義
%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 時區的名字(若是不存在爲空字符)
%% ‘%’字符

datetime模塊

datatime模塊從新封裝了time模塊,提供更多接口,提供的類有:date,time,datetime,timedelta,tzinfo。

一、date類

datetime.date(year, month, day)

靜態方法和字段

  • date.max、date.min:date對象所能表示的最大、最小日期;
  • date.resolution:date對象表示日期的最小單位。這裏是天;
  • date.today():返回一個表示當前本地日期的date對象;
  • date.fromtimestamp(timestamp):根據給定的時間戮,返回一個date對象;

方法和屬性

  • d1.year、date.month、date.day:年、月、日;
  • d1.replace(year, month, day):生成一個新的日期對象,用參數指定的年,月,日代替原有對象中的屬性。(原有對象仍保持不變)
  • d1.timetuple():返回日期對應的time.struct_time對象;
  • d1.weekday():返回weekday,若是是星期一,返回0;若是是星期2,返回1,以此類推;
  • d1.isoweekday():返回weekday,若是是星期一,返回1;若是是星期2,返回2,以此類推;
  • d1.isocalendar():返回格式如(year,month,day)的元組;
  • d1.isoformat():返回格式如'YYYY-MM-DD’的字符串;
  • d1.strftime(fmt):和time模塊format相同。

二、time類

datetime.time(hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] )

靜態方法和字段

  • time.min、time.max:time類所能表示的最小、最大時間。其中,time.min = time(0, 0, 0, 0), time.max = time(23, 59, 59, 999999);
  • time.resolution:時間的最小單位,這裏是1微秒;

方法和屬性

  • t1 = datetime.time(10,23,15)#time對象
  • t1.hour、t1.minute、t1.second、t1.microsecond:時、分、秒、微秒;
  • t1.tzinfo:時區信息;
  • t1.replace([ hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] ):建立一個新的時間對象,用參數指定的時、分、秒、微秒代替原有對象中的屬性(原有對象仍保持不變);
  • t1.isoformat():返回型如"HH:MM:SS"格式的字符串表示;
  • t1.strftime(fmt):同time模塊中的format;

三、datetime類

datetime至關於date和time結合起來。
datetime.datetime (year, month, day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] )

靜態方法和字段

  • datetime.today():返回一個表示當前本地時間的datetime對象;
  • datetime.now([tz]):返回一個表示當前本地時間的datetime對象,若是提供了參數tz,則獲取tz參數所指時區的本地時間;
  • datetime.utcnow():返回一個當前utc時間的datetime對象;#格林威治時間
  • datetime.fromtimestamp(timestamp[, tz]):根據時間戮建立一個datetime對象,參數tz指定時區信息;
  • datetime.utcfromtimestamp(timestamp):根據時間戮建立一個datetime對象;
  • datetime.combine(date, time):根據date和time,建立一個datetime對象;
  • datetime.strptime(date_string, format):將格式字符串轉換爲datetime對象;

方法和屬性

  • dt=datetime.now()#datetime對象
  • dt.year、month、day、hour、minute、second、microsecond、tzinfo:
  • dt.date():獲取date對象;
  • dt.time():獲取time對象;
  • dt. replace ([ year[ , month[ , day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] ] ] ]):
  • dt. timetuple ()
  • dt. utctimetuple ()
  • dt. toordinal ()
  • dt. weekday ()
  • dt. isocalendar ()
  • dt. isoformat ([ sep] )
  • dt. ctime ():返回一個日期時間的C格式字符串,等效於time.ctime(time.mktime(dt.timetuple()));
  • dt. strftime (format)

hashlib加密

  python中的hashlib模塊用來進行hash或者md5加密,並且這種加密是不可逆的,因此這種算法又被稱爲摘要算法。其支持Openssl庫提供的全部算法,包括md五、sha一、sha22四、sha25六、sha512等。

經常使用的屬性和方法:

  • algorithms:列出全部加密算法('md5','sha1','sha224','sha256','sha384','sha512')
  • digesti_size:產生的散列的字節大小
  • md5()/sha1():建立一個md5或者sha1加密模式的hash對象
  • update(arg):用字符串參數來更新hash對象,若是同一個has對象重複調用該方法,以下:m.update(a); m.update(b),則等於m.update(a+b)
  • digest():返回摘要,做爲二進制數據字符串值
  • hexdigest():返回摘要,做爲十六進制數據字符串值
  • copy():複製

1 logging模塊簡介

logging模塊是Python內置的標準模塊,主要用於輸出運行日誌,能夠設置輸出日誌的等級、日誌保存路徑、日誌文件回滾等;相比print,具有以下優勢:

  1. 能夠經過設置不一樣的日誌等級,在release版本中只輸出重要信息,而沒必要顯示大量的調試信息;
  2. print將全部信息都輸出到標準輸出中,嚴重影響開發者從標準輸出中查看其它數據;logging則能夠由開發者決定將信息輸出到什麼地方,以及怎麼輸出;

2 logging模塊使用

2.1 基本使用

配置logging基本的設置,而後在控制檯輸出日誌,

import logging
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")

運行時,控制檯輸出,

2016-10-09 19:11:19,434 - __main__ - INFO - Start print log
2016-10-09 19:11:19,434 - __main__ - WARNING - Something maybe fail.
2016-10-09 19:11:19,434 - __main__ - INFO - Finish

logging中能夠選擇不少消息級別,如debug、info、warning、error以及critical。經過賦予logger或者handler不一樣的級別,開發者就能夠只輸出錯誤信息到特定的記錄文件,或者在調試時只記錄調試信息。

例如,咱們將logger的級別改成DEBUG,再觀察一下輸出結果,

logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

控制檯輸出,能夠發現,輸出了debug的信息。

2016-10-09 19:12:08,289 - __main__ - INFO - Start print log
2016-10-09 19:12:08,289 - __main__ - DEBUG - Do something
2016-10-09 19:12:08,289 - __main__ - WARNING - Something maybe fail.
2016-10-09 19:12:08,289 - __main__ - INFO - Finish

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.WARNNING;

stream:指定將日誌的輸出流,能夠指定輸出到sys.stderr,sys.stdout或者文件,默認輸出到sys.stderr,當stream和filename同時指定時,stream被忽略;

2.2 將日誌寫入到文件

2.2.1 將日誌寫入到文件

設置logging,建立一個FileHandler,並對輸出消息的格式進行設置,將其添加到logger,而後將日誌寫入到指定的文件中,

import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")

log.txt中日誌數據爲,

2016-10-09 19:01:13,263 - __main__ - INFO - Start print log
2016-10-09 19:01:13,263 - __main__ - WARNING - Something maybe fail.
2016-10-09 19:01:13,263 - __main__ - INFO - Finish

2.2.2 將日誌同時輸出到屏幕和日誌文件

logger中添加StreamHandler,能夠將日誌輸出到屏幕上,

import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

console = logging.StreamHandler()
console.setLevel(logging.INFO)

logger.addHandler(handler)
logger.addHandler(console)

logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")

能夠在log.txt文件和控制檯中看到,

2016-10-09 19:20:46,553 - __main__ - INFO - Start print log
2016-10-09 19:20:46,553 - __main__ - WARNING - Something maybe fail.
2016-10-09 19:20:46,553 - __main__ - INFO - Finish

能夠發現,logging有一個日誌處理的主對象,其餘處理方式都是經過addHandler添加進去,logging中包含的handler主要有以下幾種,

handler名稱:位置;做用

StreamHandler:logging.StreamHandler;日誌輸出到流,能夠是sys.stderr,sys.stdout或者文件
FileHandler:logging.FileHandler;日誌輸出到文件
BaseRotatingHandler:logging.handlers.BaseRotatingHandler;基本的日誌回滾方式
RotatingHandler:logging.handlers.RotatingHandler;日誌回滾方式,支持日誌文件最大數量和日誌文件回滾
TimeRotatingHandler:logging.handlers.TimeRotatingHandler;日誌回滾方式,在必定時間區域內回滾日誌文件
SocketHandler:logging.handlers.SocketHandler;遠程輸出日誌到TCP/IP sockets
DatagramHandler:logging.handlers.DatagramHandler;遠程輸出日誌到UDP sockets
SMTPHandler:logging.handlers.SMTPHandler;遠程輸出日誌到郵件地址
SysLogHandler:logging.handlers.SysLogHandler;日誌輸出到syslog
NTEventLogHandler:logging.handlers.NTEventLogHandler;遠程輸出日誌到Windows NT/2000/XP的事件日誌
MemoryHandler:logging.handlers.MemoryHandler;日誌輸出到內存中的指定buffer
HTTPHandler:logging.handlers.HTTPHandler;經過"GET"或者"POST"遠程輸出到HTTP服務器

2.2.3 日誌回滾

能夠在工程目錄中看到,備份的日誌文件,

2016/10/09  19:36               732 log.txt
2016/10/09  19:36               967 log.txt.1
2016/10/09  19:36               985 log.txt.2
2016/10/09  19:36               976 log.txt.3

2.3 設置消息的等級

能夠設置不一樣的日誌等級,用於控制日誌的輸出,

日誌等級:使用範圍

FATAL:致命錯誤
CRITICAL:特別糟糕的事情,如內存耗盡、磁盤空間爲空,通常不多使用
ERROR:發生錯誤時,如IO操做失敗或者鏈接問題
WARNING:發生很重要的事件,可是並非錯誤時,如用戶登陸密碼錯誤
INFO:處理請求或者狀態變化等平常事務
DEBUG:調試過程當中使用DEBUG等級,如算法中每一個循環的中間狀態

2.4 捕獲traceback

Python中的traceback模塊被用於跟蹤異常返回信息,能夠在logging中記錄下traceback,

import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

console = logging.StreamHandler()
console.setLevel(logging.INFO)

logger.addHandler(handler)
logger.addHandler(console)

logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
try:
    open("sklearn.txt","rb")
except (SystemExit,KeyboardInterrupt):
    raise
except Exception:
    logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)

logger.info("Finish")

控制檯和日誌文件log.txt中輸出,

Start print log
Something maybe fail.
Faild to open sklearn.txt from logger.error
Traceback (most recent call last):
  File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in <module>
    open("sklearn.txt","rb")
IOError: [Errno 2] No such file or directory: 'sklearn.txt'
Finish

也可使用logger.exception(msg,_args),它等價於logger.error(msg,exc_info = True,_args),

logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)

替換爲,

logger.exception("Failed to open sklearn.txt from logger.exception")

控制檯和日誌文件log.txt中輸出,

Start print log
Something maybe fail.
Failed to open sklearn.txt from logger.exception
Traceback (most recent call last):
  File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in <module>
    open("sklearn.txt","rb")
IOError: [Errno 2] No such file or directory: 'sklearn.txt'
Finish

2.5 多模塊使用logging

主模塊mainModule.py,

import logging
import subModule
logger = logging.getLogger("mainModule")
logger.setLevel(level = logging.INFO)
handler = logging.FileHandler("log.txt")
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)

logger.addHandler(handler)
logger.addHandler(console)


logger.info("creating an instance of subModule.subModuleClass")
a = subModule.SubModuleClass()
logger.info("calling subModule.subModuleClass.doSomething")
a.doSomething()
logger.info("done with  subModule.subModuleClass.doSomething")
logger.info("calling subModule.some_function")
subModule.som_function()
logger.info("done with subModule.some_function")

子模塊subModule.py,

import logging

module_logger = logging.getLogger("mainModule.sub")
class SubModuleClass(object):
    def __init__(self):
        self.logger = logging.getLogger("mainModule.sub.module")
        self.logger.info("creating an instance in SubModuleClass")
    def doSomething(self):
        self.logger.info("do something in SubModule")
        a = []
        a.append(1)
        self.logger.debug("list a = " + str(a))
        self.logger.info("finish something in SubModuleClass")

def som_function():
    module_logger.info("call function some_function")

執行以後,在控制和日誌文件log.txt中輸出,

2016-10-09 20:25:42,276 - mainModule - INFO - creating an instance of subModule.subModuleClass
2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - creating an instance in SubModuleClass
2016-10-09 20:25:42,279 - mainModule - INFO - calling subModule.subModuleClass.doSomething
2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - do something in SubModule
2016-10-09 20:25:42,279 - mainModule.sub.module - INFO - finish something in SubModuleClass
2016-10-09 20:25:42,279 - mainModule - INFO - done with  subModule.subModuleClass.doSomething
2016-10-09 20:25:42,279 - mainModule - INFO - calling subModule.some_function
2016-10-09 20:25:42,279 - mainModule.sub - INFO - call function some_function
2016-10-09 20:25:42,279 - mainModule - INFO - done with subModule.some_function

首先在主模塊定義了logger'mainModule',並對它進行了配置,就能夠在解釋器進程裏面的其餘地方經過getLogger('mainModule')獲得的對象都是同樣的,不須要從新配置,能夠直接使用。定義的該logger的子logger,均可以共享父logger的定義和配置,所謂的父子logger是經過命名來識別,任意以'mainModule'開頭的logger都是它的子logger,例如'mainModule.sub'。

實際開發一個application,首先能夠經過logging配置文件編寫好這個application所對應的配置,能夠生成一個根logger,如'PythonAPP',而後在主函數中經過fileConfig加載logging配置,接着在application的其餘地方、不一樣的模塊中,可使用根logger的子logger,如'PythonAPP.Core','PythonAPP.Web'來進行log,而不須要反覆的定義和配置各個模塊的logger。

3 經過JSON或者YAML文件配置logging模塊

儘管能夠在Python代碼中配置logging,可是這樣並不夠靈活,最好的方法是使用一個配置文件來配置。在Python 2.7及之後的版本中,能夠從字典中加載logging配置,也就意味着能夠經過JSON或者YAML文件加載日誌的配置。

3.1 經過JSON文件配置

JSON配置文件,

{
    "version":1,
    "disable_existing_loggers":false,
    "formatters":{
        "simple":{
            "format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
        }
    },
    "handlers":{
        "console":{
            "class":"logging.StreamHandler",
            "level":"DEBUG",
            "formatter":"simple",
            "stream":"ext://sys.stdout"
        },
        "info_file_handler":{
            "class":"logging.handlers.RotatingFileHandler",
            "level":"INFO",
            "formatter":"simple",
            "filename":"info.log",
            "maxBytes":"10485760",
            "backupCount":20,
            "encoding":"utf8"
        },
        "error_file_handler":{
            "class":"logging.handlers.RotatingFileHandler",
            "level":"ERROR",
            "formatter":"simple",
            "filename":"errors.log",
            "maxBytes":10485760,
            "backupCount":20,
            "encoding":"utf8"
        }
    },
    "loggers":{
        "my_module":{
            "level":"ERROR",
            "handlers":["info_file_handler"],
            "propagate":"no"
        }
    },
    "root":{
        "level":"INFO",
        "handlers":["console","info_file_handler","error_file_handler"]
    }
}

經過JSON加載配置文件,而後經過logging.dictConfig配置logging,

import json
import logging.config
import os

def setup_logging(default_path = "logging.json",default_level = logging.INFO,env_key = "LOG_CFG"):
    path = default_path
    value = os.getenv(env_key,None)
    if value:
        path = value
    if os.path.exists(path):
        with open(path,"r") as f:
            config = json.load(f)
            logging.config.dictConfig(config)
    else:
        logging.basicConfig(level = default_level)

def func():
    logging.info("start func")

    logging.info("exec func")

    logging.info("end func")

if __name__ == "__main__":
    setup_logging(default_path = "logging.json")
    func()

3.2 經過YAML文件配置

經過YAML文件進行配置,比JSON看起來更加簡介明瞭,

version: 1
disable_existing_loggers: False
formatters:
        simple:
            format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
handlers:
    console:
            class: logging.StreamHandler
            level: DEBUG
            formatter: simple
            stream: ext://sys.stdout
    info_file_handler:
            class: logging.handlers.RotatingFileHandler
            level: INFO
            formatter: simple
            filename: info.log
            maxBytes: 10485760
            backupCount: 20
            encoding: utf8
    error_file_handler:
            class: logging.handlers.RotatingFileHandler
            level: ERROR
            formatter: simple
            filename: errors.log
            maxBytes: 10485760
            backupCount: 20
            encoding: utf8
loggers:
    my_module:
            level: ERROR
            handlers: [info_file_handler]
            propagate: no
root:
    level: INFO
    handlers: [console,info_file_handler,error_file_handler]

經過YAML加載配置文件,而後經過logging.dictConfig配置logging,

import yaml
import logging.config
import os

def setup_logging(default_path = "logging.yaml",default_level = logging.INFO,env_key = "LOG_CFG"):
    path = default_path
    value = os.getenv(env_key,None)
    if value:
        path = value
    if os.path.exists(path):
        with open(path,"r") as f:
            config = yaml.load(f)
            logging.config.dictConfig(config)
    else:
        logging.basicConfig(level = default_level)

def func():
    logging.info("start func")

    logging.info("exec func")

    logging.info("end func")

if __name__ == "__main__":
    setup_logging(default_path = "logging.yaml")
    func()

subprocess模塊

subprocess是Python 2.4中新增的一個模塊,它容許你生成新的進程,鏈接到它們的 input/output/error 管道,並獲取它們的返回(狀態)碼。這個模塊的目的在於替換幾個舊的模塊和方法,如:

  • os.system
  • os.spawn*

1. subprocess模塊中的經常使用函數

函數 描述
subprocess.run() Python 3.5中新增的函數。執行指定的命令,等待命令執行完成後返回一個包含執行結果的CompletedProcess類的實例。
subprocess.call() 執行指定的命令,返回命令執行狀態,其功能相似於os.system(cmd)。
subprocess.check_call() Python 2.5中新增的函數。 執行指定的命令,若是執行成功則返回狀態碼,不然拋出異常。其功能等價於subprocess.run(..., check=True)。
subprocess.check_output() Python 2.7中新增的的函數。執行指定的命令,若是執行狀態碼爲0則返回命令執行結果,不然拋出異常。
subprocess.getoutput(cmd) 接收字符串格式的命令,執行命令並返回執行結果,其功能相似於os.popen(cmd).read()和commands.getoutput(cmd)。
subprocess.getstatusoutput(cmd) 執行cmd命令,返回一個元組(命令執行狀態, 命令執行結果輸出),其功能相似於commands.getstatusoutput()。

說明:

  1. 在Python 3.5以後的版本中,官方文檔中提倡經過subprocess.run()函數替代其餘函數來使用subproccess模塊的功能;
  2. 在Python 3.5以前的版本中,咱們能夠經過subprocess.call(),subprocess.getoutput()等上面列出的其餘函數來使用subprocess模塊的功能;
  3. subprocess.run()、subprocess.call()、subprocess.check_call()和subprocess.check_output()都是經過對subprocess.Popen的封裝來實現的高級函數,所以若是咱們須要更復雜功能時,能夠經過subprocess.Popen來完成。
  4. subprocess.getoutput()和subprocess.getstatusoutput()函數是來自Python 2.x的commands模塊的兩個遺留函數。它們隱式的調用系統shell,而且不保證其餘函數所具備的安全性和異常處理的一致性。另外,它們從Python 3.3.4開始才支持Windows平臺。

2. 上面各函數的定義及參數說明

函數參數列表:

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, universal_newlines=False)

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None)

subprocess.getstatusoutput(cmd)

subprocess.getoutput(cmd)

參數說明:

  • args: 要執行的shell命令,默認應該是一個字符串序列,如['df', '-Th']或('df', '-Th'),也能夠是一個字符串,如'df -Th',可是此時須要把shell參數的值置爲True。
  • shell: 若是shell爲True,那麼指定的命令將經過shell執行。若是咱們須要訪問某些shell的特性,如管道、文件名通配符、環境變量擴展功能,這將是很是有用的。固然,python自己也提供了許多相似shell的特性的實現,如glob、fnmatch、os.walk()、os.path.expandvars()、os.expanduser()和shutil等。
  • check: 若是check參數的值是True,且執行命令的進程以非0狀態碼退出,則會拋出一個CalledProcessError的異常,且該異常對象會包含 參數、退出狀態碼、以及stdout和stderr(若是它們有被捕獲的話)。
  • stdout, stderr:
  • run()函數默認不會捕獲命令執行結果的正常輸出和錯誤輸出,若是咱們向獲取這些內容須要傳遞subprocess.PIPE,而後能夠經過返回的CompletedProcess類實例的stdout和stderr屬性或捕獲相應的內容;
  • call()和check_call()函數返回的是命令執行的狀態碼,而不是CompletedProcess類實例,因此對於它們而言,stdout和stderr不適合賦值爲subprocess.PIPE;
  • check_output()函數默認就會返回命令執行結果,因此不用設置stdout的值,若是咱們但願在結果中捕獲錯誤信息,能夠執行stderr=subprocess.STDOUT。
  • input: 該參數是傳遞給Popen.communicate(),一般該參數的值必須是一個字節序列,若是universal_newlines=True,則其值應該是一個字符串。
  • universal_newlines: 該參數影響的是輸入與輸出的數據格式,好比它的值默認爲False,此時stdout和stderr的輸出是字節序列;當該參數的值設置爲True時,stdout和stderr的輸出是字符串。

3. subprocess.CompletedProcess類介紹

須要說明的是,subprocess.run()函數是Python3.5中新增的一個高級函數,其返回值是一個subprocess.CompletedPorcess類的實例,所以,subprocess.completedPorcess類也是Python 3.5中才存在的。它表示的是一個已結束進程的狀態信息,它所包含的屬性以下:

  • args: 用於加載該進程的參數,這多是一個列表或一個字符串
  • returncode: 子進程的退出狀態碼。一般狀況下,退出狀態碼爲0則表示進程成功運行了;一個負值-N表示這個子進程被信號N終止了
  • stdout: 從子進程捕獲的stdout。這一般是一個字節序列,若是run()函數被調用時指定universal_newlines=True,則該屬性值是一個字符串。若是run()函數被調用時指定stderr=subprocess.STDOUT,那麼stdout和stderr將會被整合到這一個屬性中,且stderr將會爲None
  • stderr: 從子進程捕獲的stderr。它的值與stdout同樣,是一個字節序列或一個字符串。若是stderr滅有被捕獲的話,它的值就爲None
  • check_returncode(): 若是returncode是一個非0值,則該方法會拋出一個CalledProcessError異常。

4. 實例

subprocess.run()

>>> 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.call()

>>> subprocess.call(['ls',  '-l'])
總用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 視頻
drwxr-xr-x  2 wader wader   4096 12月  7  2015 圖片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文檔
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下載
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音樂
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
0
>>> subprocess.call('ls -l', shell=True)
總用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 視頻
drwxr-xr-x  2 wader wader   4096 12月  7  2015 圖片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文檔
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下載
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音樂
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
0
>>> subprocess.call(['ls',  '-l'], stdout=subprocess.DEVNULL)
0
>>> subprocess.call(['ls',  '-l', '/test'])
ls: 沒法訪問/test: 沒有那個文件或目錄
2
suprocess.check_call()
>>> subprocess.check_call(['ls',  '-l'])
總用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 視頻
drwxr-xr-x  2 wader wader   4096 12月  7  2015 圖片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文檔
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下載
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音樂
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
0
>>> subprocess.check_call('ls -l', shell=True)
總用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 視頻
drwxr-xr-x  2 wader wader   4096 12月  7  2015 圖片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文檔
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下載
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音樂
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
0
>>> subprocess.check_call('ls -l /test', shell=True)
ls: 沒法訪問/test: 沒有那個文件或目錄
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.4/subprocess.py", line 557, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'ls -l /test' returned non-zero exit status 2

sbuprocess.check_output()

>>> ret = subprocess.check_output(['ls',  '-l'])
>>> print(ret)
b' \xe5\x85\xac\xe5\x85\xb1\xe7\x9a\x84\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe6\xa8\xa1\xe6\x9d\xbf\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe8\xa7\x86\xe9\xa2\x91\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe5\x9b\xbe\xe7\x89\x87\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe6\x96\x87\xe6\xa1\xa3\ndrwxr-xr-x  2 wader wader   4096  4\xe6\x9c\x88 13  2016 \xe4\xb8\x8b\xe8\xbd\xbd\ndrwxr-xr-x  2 wader wader   4096 12\xe6\x9c\x88  7  2015 \xe9\x9f\xb3\xe4\xb9\x90\ndrwxr-xr-x  7 wader wader   4096  5\xe6\x9c\x88 26  2016 \xe6\xa1\x8c\xe9\x9d\xa2\n'
>>> ret = subprocess.check_output(['ls',  '-l'], universal_newlines=True)
>>> print(ret)
總用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 視頻
drwxr-xr-x  2 wader wader   4096 12月  7  2015 圖片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文檔
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下載
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音樂
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面

subprocess.getoutput()與subprocess.getstatusoutput()

>>> ret = subprocess.getoutput('ls -l')
>>> print(ret)
總用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 視頻
drwxr-xr-x  2 wader wader   4096 12月  7  2015 圖片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文檔
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下載
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音樂
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l')
>>> print(retcode)
0
>>> print(output)
總用量 160
drwxr-xr-x  2 wader wader   4096 12月  7  2015 公共的
drwxr-xr-x  2 wader wader   4096 12月  7  2015 模板
drwxr-xr-x  2 wader wader   4096 12月  7  2015 視頻
drwxr-xr-x  2 wader wader   4096 12月  7  2015 圖片
drwxr-xr-x  2 wader wader   4096 12月  7  2015 文檔
drwxr-xr-x  2 wader wader   4096  4月 13  2016 下載
drwxr-xr-x  2 wader wader   4096 12月  7  2015 音樂
drwxr-xr-x  7 wader wader   4096  5月 26  2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l /test')
>>> print(retcode)
2
>>> print(output)
ls: 沒法訪問/test: 沒有那個文件或目錄

3、subprocess.Popen介紹

該類用於在一個新的進程中執行一個子程序。前面咱們提到過,上面介紹的這些函數都是基於subprocess.Popen類實現的,經過使用這些被封裝後的高級函數能夠很方面的完成一些常見的需求。因爲subprocess模塊底層的進程建立和管理是由Popen類來處理的,所以,當咱們沒法經過上面哪些高級函數來實現一些不太常見的功能時就能夠經過subprocess.Popen類提供的靈活的api來完成。

1.subprocess.Popen的構造函數

class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, 
    preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False,
    startup_info=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())

參數說明:

  • args: 要執行的shell命令,能夠是字符串,也能夠是命令各個參數組成的序列。當該參數的值是一個字符串時,該命令的解釋過程是與平臺相關的,所以一般建議將args參數做爲一個序列傳遞。
  • bufsize: 指定緩存策略,0表示不緩衝,1表示行緩衝,其餘大於1的數字表示緩衝區大小,負數 表示使用系統默認緩衝策略。
  • stdin, stdout, stderr: 分別表示程序標準輸入、輸出、錯誤句柄。
  • preexec_fn: 用於指定一個將在子進程運行以前被調用的可執行對象,只在Unix平臺下有效。
  • close_fds: 若是該參數的值爲True,則除了0,1和2以外的全部文件描述符都將會在子進程執行以前被關閉。
  • shell: 該參數用於標識是否使用shell做爲要執行的程序,若是shell值爲True,則建議將args參數做爲一個字符串傳遞而不要做爲一個序列傳遞。
  • cwd: 若是該參數值不是None,則該函數將會在執行這個子進程以前改變當前工做目錄。
  • env: 用於指定子進程的環境變量,若是env=None,那麼子進程的環境變量將從父進程中繼承。若是env!=None,它的值必須是一個映射對象。
  • universal_newlines: 若是該參數值爲True,則該文件對象的stdin,stdout和stderr將會做爲文本流被打開,不然他們將會被做爲二進制流被打開。
  • startupinfo和creationflags: 這兩個參數只在Windows下有效,它們將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如主窗口的外觀,進程優先級等。

2. subprocess.Popen類的實例可調用的方法

方法 描述
Popen.poll() 用於檢查子進程(命令)是否已經執行結束,沒結束返回None,結束後返回狀態碼。
Popen.wait(timeout=None) 等待子進程結束,並返回狀態碼;若是在timeout指定的秒數以後進程尚未結束,將會拋出一個TimeoutExpired異常。
Popen.communicate(input=None, timeout=None) 該方法可用來與進程進行交互,好比發送數據到stdin,從stdout和stderr讀取數據,直到到達文件末尾。
Popen.send_signal(signal) 發送指定的信號給這個子進程。
Popen.terminate() 中止該子進程。
Popen.kill() 殺死該子進程。

關於communicate()方法的說明:

  • 該方法中的可選參數 input 應該是將被髮送給子進程的數據,或者如沒有數據發送給子進程,該參數應該是None。input參數的數據類型必須是字節串,若是universal_newlines參數值爲True,則input參數的數據類型必須是字符串。
  • 該方法返回一個元組(stdout_data, stderr_data),這些數據將會是字節穿或字符串(若是universal_newlines的值爲True)。
  • 若是在timeout指定的秒數後該進程尚未結束,將會拋出一個TimeoutExpired異常。捕獲這個異常,而後從新嘗試通訊不會丟失任何輸出的數據。可是超時以後子進程並無被殺死,爲了合理的清除相應的內容,一個好的應用應該手動殺死這個子進程來結束通訊。
  • 須要注意的是,這裏讀取的數據是緩衝在內存中的,因此,若是數據大小很是大或者是無限的,就不該該使用這個方法。

3. subprocess.Popen使用實例

實例1:

>>> import subprocess
>>>
>>> p = subprocess.Popen('df -Th', stdout=subprocess.PIPE, shell=True)
>>> print(p.stdout.read())
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/vda1      ext4       40G   12G   26G  31% /
devtmpfs       devtmpfs  3.9G     0  3.9G   0% /dev
tmpfs          tmpfs     3.9G     0  3.9G   0% /dev/shm
tmpfs          tmpfs     3.9G  386M  3.5G  10% /run
tmpfs          tmpfs     3.9G     0  3.9G   0% /sys/fs/cgroup
tmpfs          tmpfs     783M     0  783M   0% /run/user/0
tmpfs          tmpfs     783M     0  783M   0% /run/user/1000

實例2:

>>> 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')
>>> out,err = obj.communicate()
>>> print(out)
1
2
3

>>> print(err)

實例3:

>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> out,err = obj.communicate(input='print(1) \n')
>>> print(out)
1

>>> print(err)

實例4:

實現相似df -Th | grep data命令的功能,實際上就是實現shell中管道的共功能。

>>> 
>>> p1 = subprocess.Popen(['df', '-Th'], stdout=subprocess.PIPE)
>>> p2 = subprocess.Popen(['grep', 'data'], stdin=p1.stdout, stdout=subprocess.PIPE)
>>> out,err = p2.communicate()
>>> print(out)
/dev/vdb1      ext4      493G  4.8G  463G   2% /data
/dev/vdd1      ext4     1008G  420G  537G  44% /data1
/dev/vde1      ext4      985G  503G  432G  54% /data2

>>> print(err)
None

4、總結

那麼咱們到底該用哪一個模塊、哪一個函數來執行命令與系統及系統進行交互呢?下面咱們來作個總結:

  • 首先應該知道的是,Python2.4版本引入了subprocess模塊用來替換os.system()、os.popen()、os.spawn*()等函數以及commands模塊;也就是說若是你使用的是Python 2.4及以上的版本就應該使用subprocess模塊了。
  • 若是你的應用使用的Python 2.4以上,可是是Python 3.5如下的版本,Python官方給出的建議是使用subprocess.call()函數。Python 2.5中新增了一個subprocess.check_call()函數,Python 2.7中新增了一個subprocess.check_output()函數,這兩個函數也能夠按照需求進行使用。
  • 若是你的應用使用的是Python 3.5及以上的版本(目前應該還不多),Python官方給出的建議是儘可能使用subprocess.run()函數。
  • 當subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()這些高級函數沒法知足需求時,咱們可使用subprocess.Popen類來實現咱們須要的複雜功能。

json ,pickle模塊

JSON(JavaScript Object Notation, JS 對象標記) 是一種輕量級的數據交換格式。JSON的數據格式其實就是python裏面的字典格式,裏面能夠包含方括號括起來的數組,也就是python裏面的列表。

在python中,有專門處理json格式的模塊—— json 和 picle模塊

Json 模塊提供了四個方法: dumps、dump、loads、load

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

一. dumps 和 dump:

dumps和dump 序列化方法

dumps只完成了序列化爲str,

   dump必須傳文件描述符,將序列化的str保存到文件中

查看源碼:

def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):
    # Serialize ``obj`` to a JSON formatted ``str``.
    # 序列號 「obj」 數據類型 轉換爲 JSON格式的字符串
def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):
    """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
    ``.write()``-supporting file-like object).
     我理解爲兩個動做,一個動做是將」obj「轉換爲JSON格式的字符串,還有一個動做是將字符串寫入到文件中,也就是說文件描述符fp是必需要的參數 """
>>> import json
>>> json.dumps([])    # dumps能夠格式化全部的基本數據類型爲字符串
'[]'
>>> json.dumps(1)    # 數字
'1'
>>> json.dumps('1')   # 字符串
'"1"'
>>> dict = {"name":"Tom", "age":23}  
>>> json.dumps(dict)     # 字典
'{"name": "Tom", "age": 23}'
a = {"name":"Tom", "age":23}
with open("test.json", "w", encoding='utf-8') as f:
    # indent 超級好用,格式化保存字典,默認爲None,小於0爲零個空格
    f.write(json.dumps(a, indent=4))
    # json.dump(a,f,indent=4)   # 和上面的效果同樣

保存的文件效果:

img

二. loads 和 load

loads和load 反序列化方法

loads 只完成了反序列化,

   load 只接收文件描述符,完成了讀取文件和反序列化

查看源碼:

def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
    """Deserialize ``s`` (a ``str`` instance containing a JSON document) to a Python object.
       將包含str類型的JSON文檔反序列化爲一個python對象"""
def load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
    """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object.
        將一個包含JSON格式數據的可讀文件飯序列化爲一個python對象"""

實例:

>>> json.loads('{"name":"Tom", "age":23}')
{'age': 23, 'name': 'Tom'}
import json
with open("test.json", "r", encoding='utf-8') as f:
    aa = json.loads(f.read())
    f.seek(0)
    bb = json.load(f)    # 與 json.loads(f.read())
print(aa)
print(bb)

# 輸出:
{'name': 'Tom', 'age': 23}
{'name': 'Tom', 'age': 23}

三. json 和 pickle 模塊

json模塊和pickle模塊都有 dumps、dump、loads、load四種方法,並且用法同樣。

不用的是json模塊序列化出來的是通用格式,其它編程語言都認識,就是普通的字符串,

而picle模塊序列化出來的只有python能夠認識,其餘編程語言不認識的,表現爲亂碼

不過picle能夠序列化函數,可是其餘文件想用該函數,在該文件中須要有該文件的定義(定義和參數必須相同,內容能夠不一樣)

四. python對象(obj) 與json對象的對應關係

+-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict              | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str               | string        |
    +-------------------+---------------+
    | int, float        | number        |
    +-------------------+---------------+
    | True              | true          |
    +-------------------+---------------+
    | False             | false         |
    +-------------------+---------------+
    | None              | null          |
    +-------------------+---------------+

五. 總結

\1. json序列化方法:

dumps:無文件操做            dump:序列化+寫入文件

\2. json反序列化方法:

loads:無文件操做              load: 讀文件+反序列化

\3. json模塊序列化的數據 更通用

picle模塊序列化的數據 僅python可用,但功能強大,能夠序列號函數

\4. json模塊能夠序列化和反序列化的 數據類型 見 python對象(obj) 與json對象的對應關係表

\5. 格式化寫入文件利用 indent = 4

ElementTree是python的XML處理模塊

ElementTree是python的XML處理模塊,它提供了一個輕量級的對象模型。它在Python2.5之後成爲Python標準庫的一部分,可是Python2.4以前須要單獨安裝。在使用ElementTree模塊時,須要import xml.etree.ElementTree的操做。

ElementTree表示整個XML節點樹,而Element表示節點數中的一個單獨的節點。

構建

ElementTree(tag),其中tag表示根節點,初始化一個ElementTree對象。

Element(tag, attrib={}, **extra)函數用來構造XML的一個根節點,其中tag表示根節點的名稱,attrib是一個可選項,表示節點的屬性。

SubElement(parent, tag, attrib={}, **extra)用來構造一個已經存在的節點的子節點

Element.text和SubElement.text表示element對象的額外的內容屬性,Element.tag和Element.attrib分別表示element對象的標籤和屬性。

ElementTree.write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml'),函數新建一個XML文件,而且將節點數數據寫入XML文件中。

#encoding=utf-8
import xml.etree.ElementTree as ET

#新建xml文件
def buildNewsXmlFile():
        #設置一個新節點,並設置其標籤爲root
        root = ET.Element("root")

        #在root下新建兩個子節點,設置其名稱分別爲sina和chinabyte
        sina = ET.SubElement(root, "sina")
        chinabyte = ET.SubElement(root, "chinabyte")

        #在sina下新建兩個子節點,設置其節點名稱分別爲number和first
        sina_number = ET.SubElement(sina, "number")
        sina_number.text = "1"
        sina_first = ET.SubElement(sina, "first")
        sina_first.text = "http://roll.tech.sina.com.cn/internet_all/index_1.shtml"

        #在chinabyte下新建兩個子節點,設置其節點名稱爲number和first
        chinabyte_number = ET.SubElement(chinabyte, "number")
        chinabyte_number.text = "1"
        chinabyte_first = ET.SubElement(chinabyte, "first")
        chinabyte_first.text = "http://www.chinabyte.com/more/124566.shtml"

        #將節點數信息保存在ElementTree中,而且保存爲XML格式文件
        tree = ET.ElementTree(root)
        tree.write("urlfile.xml")

解析和修改XML文件

ElementTree.parse(source, parser=None),將xml文件加載並返回ElementTree對象。parser是一個可選的參數,若是爲空,則默認使用標準的XMLParser解析器。

ElementTree.getroot(),獲得根節點。返回根節點的element對象。

Element.remove(tag),刪除root下名稱爲tag的子節點

如下函數,ElementTree和Element的對象都包含。

find(match),獲得第一個匹配match的子節點,match能夠是一個標籤名稱或者是路徑。返回個element

findtext(match,default=None),獲得第一個配置的match的element的內容

findall(match),獲得匹配match下的全部的子節點,match能夠是一個標籤或者是路徑,它會返回一個list,包含匹配的elements的信息

iter(tag),建立一個以當前節點爲根節點的iterator。

這裏有一個xml文件

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

如今是解析xml文件的代碼

#解析Xml文件
def parseXmlFile(xml_name):
        #將XMl文件加載並返回一個ELementTree對象
        tree = ET.parse(xml_name)

        #獲得第一個匹配sina標籤的Element對象
        sina = tree.find("contry")

        #獲得sina的SubElement
        for sub_tag in sina:
                print sub_tag.text

        #獲得全部匹配sina標籤的Element對象的list集合
        list_contry = tree.findall("contry")

        for contry in list_contry:
                for sub_tag in contry:
                        print sub_tag.text
    #修改xml文件
        for rank in tree.iter('rank')
        new_rank = int(rank.text)+1
        rank.text = str(new_rank)
        rank.set('updated', 'yes')
        tree.write(xml_name)

第一次的輸出是:1,2008,14100

第二次的輸出是:1,2008,14100,4,2011,59900,68,2011,13600

修改後的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>

configparser 簡介

configparser 是 Pyhton 標準庫中用來解析配置文件的模塊,而且內置方法和字典很是接近。Python2.x 中名爲 ConfigParser,3.x 已改名小寫,並加入了一些新功能。
配置文件的格式以下:

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes

[bitbucket.org]
User = Tom

[topsecret.com]
Port: 50022
ForwardX11: no

「[ ]」包含的爲 section,section 下面爲相似於 key - value 的配置內容;
configparser 默認支持 ‘=’ ‘:’ 兩種分隔。

configparser 經常使用方法

初始化實例

使用 configparser 首先須要初始化實例,並讀取配置文件:

>>> import configparser
>>> config = configparser.ConfigParser()    # 注意大小寫
>>> config.read("config.ini")   # 配置文件的路徑
["config.ini"]

或者能夠直接讀字典

>>> parser = configparser.ConfigParser()
>>> parser.read_dict({'section1': {'key1': 'value1',
...                                'key2': 'value2',
...                                'key3': 'value3'},
...                   'section2': {'keyA': 'valueA',
...                                'keyB': 'valueB',
...                                'keyC': 'valueC'},
...                   'section3': {'foo': 'x',
...                                'bar': 'y',
...                                'baz': 'z'}
... })

獲取全部 sections

>>> config.sections()
['bitbucket.org', 'topsecret.com']    # 注意會過濾掉[DEFAULT]

獲取指定 section 的 keys & values

>>> config.items('topsecret.com')
>>>> [('port', '50022'), ('forwardx11', 'no')]    # 注意items()返回的字符串會全變成小寫

獲取指定 section 的 keys

>>> config.options('topsecret.com')
['Port', 'ForwardX11']


>>> for option in config['topsecret.com']:
...     print(option)
Port
ForwardX11

獲取指定 key 的 value

>>> config['bitbucket.org']['User']
'Tom'

>>> config.get('bitbucket.org', 'User')
'Tom'
>>> config.getint('topsecret.com', 'Port')
50022

檢查

>>> 'DEFAULT' in config
True
>>> 'test' in config['section_test']
False
>>> 'Tom' in config['bitbucket.org']['User']
True

>>> config.has_section('bitbucket.org')
True
>>> config.has_option('section_test', 'test')
False

添加

>>> config.add_section('Section_1')
>>> config.set('Section_1', 'key_1', 'value_1')    # 注意鍵值是用set()方法
>>> config.write(open('config.ini', 'w'))    # 必定要寫入才生效

刪除

>>> config.remove_option('Section_1', 'key_1')
True
>>> config.remove_section('Section_1')
True
>>> config.clear()  # 清空除[DEFAULT]以外全部內容
>>> config.write(open('config.ini', 'w'))

關於 [DEFAULT]

通常包含 ini 格式配置文件的默認項,因此 configparser 部分方法會自動跳過這個 section 。
前面已經提到 sections() 是獲取不到的,還有刪除方法對 [DEFAULT] 也無效:

>>> config.remove_section('DEFAULT')
False
>>> config.clear()
>>> 'DEFAULT' in config
True
>>> 'ForwardX11' in config['DEFAULT']
True
>>> config.sections()
[]

但指定刪除和修改 [DEFAULT] 裏的 keys & values 是能夠的:

>>> config.remove_option('DEFAULT', 'ForwardX11')
True
>>> config.set('DEFAULT', 'ForwardX11','no')
>>> config['DEFAULT']['ForwardX11']
'no'

還有個特殊的是,has_section() 也無效,能夠和 in 區別使用

>>> config.has_section('DEFAULT')
False
>>> 'DEFAULT' in config
True

randmon(獲取隨機數)

random —— 生成僞隨機數,該模塊爲各類分佈實現僞隨機數生成器。咱們來看看random模塊經常使用的幾個函數的介紹:

1、針對整數的方法:

random.randrange(stop)

random.randrange(start, stop[, step])
等同於choice(range(start, stop, step)),但不實際建立range對象。

>>> import random
>>> print(random.randrange(4))         #返回0~3的隨機整數
1
>>> print(random.randrange(1, 9))       #返回1~8的隨機整數
8
>>> print(random.randrange(1, 11, 2))    #返回1~10的隨機奇數
3

random.randint(a, b)
返回一個隨機整數N,a <= N <= b, 等同於randrange(a, b+1)。

>>> print(random.randint(1, 10))        #返回[1, 10]的隨機整數
8
>>> print(random.randint(-10, -1))      #返回[-10, -1]的隨機整數,不能寫成random.randint(-1, -10)
-5

2、針對序列的方法:
random.choice(seq)
從非空序列中返回一個隨機元素,若是序列爲空,則引起IndexError。

>>> print(random.choice('BHasdgiHUI1234'))   #返回一個字符
I
>>> print(random.choice(['apple', 'peach', 'pear']))   #返回列表中一個隨機一個元素
pear
>>> print(random.choice(('Bob', 'Jhon', 'Micheal')))  #返回元組中一個隨機元素
Jhon

random.choices(population, weight=None, *, cum_weight=None, k=1)
從可替代的population序列中隨機取出k個元素組成列表,返回該列表。weight是相對權重序列,cum_weight是累計權重,同時制定權重weight和累計權重cum_weight,會產生類型錯誤。

>>> print(random.choices(['red', 'yellow','green', 'blue', 'black', 'pink', 'purple', 'white'], k=4))  
['red', 'red', 'purple', 'black']
>>> print(random.choices(['apple', 'peach', 'pear'], [1, 2, 3], k=4))
['pear', 'pear', 'pear', 'peach']
>>> print(random.choices(['apple', 'peach', 'pear'], [6, 12, 2], k=4))
['peach', 'peach', 'pear', 'pear']

random.shuffle(x [,random])
從新排列序列(洗牌)

>>> seq = ['red1','yellow2','blue3', 'green4' ]
>>> random.shuffle(seq)    #列表從新排序
>>> print(seq)
['red1', 'blue3', 'green4', 'yellow2']

random.sample(population, k)
返回一個從序列population中隨機抽取K個不重複的元素組成的新隊列。用於不可替換的隨機抽樣。返回一個新的列表,不破壞原有列表。若是新隊列的長度k大於原隊列population的長度,則會引起ValueError錯誤。

>>> print(random.sample(['a', 'b', 'c', 'd', 'e', '1', '2', '3'], 2))  #列表中隨機抽取2個元素組成新的列表
['d', 'b']
>>> print(''.join(random.sample("ahoiNUAI483*4", 4)))  
UohI

3、真值分佈:

random.random()
返回一個隨機的浮點數,範圍[0, 1)

>>> print(random.random())
0.5867129667371662

random.uniform(a, b)
返回一個a和b之間的隨機浮點數,若是a>b,則返回b和a之間的浮點數。a和b均可能出如今結果中。

>>> print(random.uniform(1, 10))
5.961863773592117
>>> print(random.uniform(2,6))
3.2723769810535543

shutil模塊


引入: import shutil

copy()

功能:複製文件
格式:shutil.copy('來源文件','目標地址')
返回值:複製以後的路徑

copy2()

功能:複製文件,保留元數據
格式:shutil.copy2('來源文件','目標地址')
返回值:複製以後的路徑

copyfileobj()

將一個文件的內容拷貝的另一個文件當中
格式:shutil.copyfileobj(open(來源文件,'r'),open('目標文件','w'))
返回值:無

copyfile()

功能:將一個文件的內容拷貝的另一個文件當中
格式:shutil.copyfile(來源文件,目標文件)
返回值:目標文件的路徑

copytree()

功能:複製整個文件目錄
格式:shutil.copytree(來源目錄,目標目錄)
返回值:目標目錄的路徑
注意:不管文件夾是否爲空,都可以複製,並且會複製文件夾中的全部內容

copymode()

功能:拷貝權限

copystat()

功能:拷貝元數據(狀態)

rmtree()

功能:移除整個目錄,不管是否空
格式:shutil.rmtree(目錄路徑)
返回值:無

move()

功能:移動文件或者文件夾
格式:shutil.move(來源地址,目標地址)
返回值:目標地址

which()

功能:檢測命令對應的文件路徑
格式:shutil.which(‘命令字符串’)
返回值:命令文件所在位置
注意:window和linux不太同樣。 window的命令都是.exe結尾,linux則不是

disk_usage()

功能:檢測磁盤使用信息
格式:disk_usage(‘盤符’)
返回值:元組

歸檔和解包操做


歸檔:將多個文件合併到一個文件當中,這種操做方式就是歸檔。

解包:將歸檔的文件進行釋放。

壓縮:壓縮時將多個文件進行有損或者無損的合併到一個文件當中。

解壓縮:就是壓縮的反向操做,將壓縮文件中的多個文件,釋放出來。

注意:壓縮屬於歸檔!

make_archive()

功能:歸檔函數,歸檔操做
格式:shutil.make_archive('目標文件路徑','歸檔文件後綴','須要歸檔的目錄')
返回值:歸檔文件的最終路徑

unpack_archive()

功能:解包操做
格式:shutil.unpack_archive('歸檔文件路徑','解包目標文件夾')
返回值:None
注意:文件夾不存在會新建文件夾

get_archive_formats()

功能:獲取當前系統已註冊的歸檔文件格式(後綴)
格式:shutil.get_archive_formats()
返回值:列表   [(後綴,解釋),(後綴,解釋),(後綴,解釋)...]

get_unpack_formats()

功能:獲取當前系統已經註冊的解包文件格式(後綴)
格式:shutil.get_unpack_formats()
返回值:列表   [(後綴,解釋),(後綴,解釋),(後綴,解釋)...]

paramiko

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

一、下載安裝

pycrypto,因爲 paramiko 模塊內部依賴pycrypto,因此先下載安裝pycrypto``pip3 install pycrypto``pip3 install paramiko

二、模塊使用

#!/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()

requests

Python標準庫中提供了:urllib等模塊以供Http請求,可是,它的 API 太渣了。它是爲另外一個時代、另外一個互聯網所建立的。它須要巨量的工做,甚至包括各類方法覆蓋,來完成最簡單的任務。javascript:void(0);)

import urllib.request
f = urllib.request.urlopen('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
result = f.read().decode('utf-8')
import urllib.request
req = urllib.request.Request('http://www.example.com/')
req.add_header('Referer', 'http://www.python.org/')
r = urllib.request.urlopen(req)
result = f.read().decode('utf-8')

Requests 是使用 Apache2 Licensed 許可證的 基於Python開發的HTTP 庫,其在Python內置模塊的基礎上進行了高度的封裝,從而使得Pythoner進行網絡請求時,變得美好了許多,使用Requests能夠垂手可得的完成瀏覽器可有的任何操做。

一、安裝模塊

pip3 install requests

二、使用模塊

# 一、無參數實例
import requests
ret = requests.get('https://github.com/timeline.json')
print(ret.url)
print(ret.text)
# 二、有參數實例 
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
ret = requests.get("http://httpbin.org/get", params=payload) 
print(ret.url)
print(ret.text)
# 一、基本POST實例
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
ret = requests.post("http://httpbin.org/post", data=payload)
 
print(ret.text)
 
 
# 二、發送請求頭和數據實例
 
import requests
import json
 
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
headers = {'content-type': 'application/json'}
 
ret = requests.post(url, data=json.dumps(payload), headers=headers)
 
print(ret.text)
print(ret.cookies)
requests.get(url, params=None, **kwargs)
requests.post(url, data=None, json=None, **kwargs)
requests.put(url, data=None, **kwargs)
requests.head(url, **kwargs)
requests.delete(url, **kwargs)
requests.patch(url, data=None, **kwargs)
requests.options(url, **kwargs)
 
# 以上方法均是在此方法的基礎上構建
requests.request(method, url, **kwargs)

三、Http請求和XML實例

實例:檢測QQ帳號是否在線

import urllib
import requests
from xml.etree import ElementTree as ET

# 使用內置模塊urllib發送HTTP請求,或者XML格式內容
"""
f = urllib.request.urlopen('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
result = f.read().decode('utf-8')
"""


# 使用第三方模塊requests發送HTTP請求,或者XML格式內容
r = requests.get('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508')
result = r.text

# 解析XML格式內容
node = ET.XML(result)

# 獲取內容
if node.text == "Y":
    print("在線")
else:
    print("離線")

實例:查看火車停靠信息

import urllib
import requests
from xml.etree import ElementTree as ET

# 使用內置模塊urllib發送HTTP請求,或者XML格式內容
"""
f = urllib.request.urlopen('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=')
result = f.read().decode('utf-8')
"""

# 使用第三方模塊requests發送HTTP請求,或者XML格式內容
r = requests.get('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=G666&UserID=')
result = r.text

# 解析XML格式內容
root = ET.XML(result)
for node in root.iter('TrainDetailInfo'):
    print(node.find('TrainStation').text,node.find('StartTime').text,node.tag,node.attrib)

paramiko模塊

import paramiko

# 建立SSH對象
ssh = paramiko.SSHClient()
# 容許鏈接不在known_hosts文件上的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 鏈接服務器
ssh.connect(hostname="192.168.0.99", port=22, username="root", password="rootroot")
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取結果
result = stdout.read().decode()
# 獲取錯誤提示(stdout、stderr只會輸出其中一個)
err = stderr.read()
# 關閉鏈接
ssh.close()
print(stdin, result, err)

注:若是註釋「ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())」這句,會報錯。

img

相似問題能夠爲linux系統中~/.ssh/known_hosts文件中的內容。

2、實現SFTP功能

import paramiko
# 鏈接虛擬機centos上的ip及端口
transport = paramiko.Transport(("192.168.0.99", 22))
transport.connect(username="root", password="rootroot")
# 將實例化的Transport做爲參數傳入SFTPClient中
sftp = paramiko.SFTPClient.from_transport(transport)
# 將「calculator.py」上傳到filelist文件夾中
sftp.put('D:\python庫\Python_shell\day05\calculator.py', '/filelist/calculator.py')
# 將centos中的aaa.txt文件下載到桌面
sftp.get('/filedir/aaa.txt', r'C:\Users\duany_000\Desktop\test_aaa.txt')
transport.close()

3、使用祕鑰實現SSH功能

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa31')
# 建立SSH對象
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 鏈接服務器
ssh.connect(hostname='192.168.79.9', port=22, username='root', pkey=private_key)
stdin, stdout, stderr = ssh.exec_command('ifconfig')
res_out = stdout.read()
print(res_out.decode())
ssh.close()

4、使用祕鑰實現SFTP功能

import paramiko
private_key = paramiko.RSAKey.from_private_key_file('id_rsa31')
# 鏈接虛擬機centos上的ip及端口
transport = paramiko.Transport(("192.168.79.9", 22))
transport.connect(username="root", pkey=private_key)
# 將實例化的Transport做爲參數傳入SFTPClient中
sftp = paramiko.SFTPClient.from_transport(transport)
# 將「calculator.py」上傳到filelist文件夾中
sftp.put('D:\python庫\Python_shell\day05\calculator.py', '/filedir/calculator.py')
# 將centos中的aaa.txt文件下載到桌面
sftp.get('/filedir/oldtext.txt', r'C:\Users\duany_000\Desktop\oldtext.txt')
transport.close()
相關文章
相關標籤/搜索