python3經常使用標準庫

python3經常使用標準庫

趁着有時間,把一些我用過的經常使用標準庫進行整理和複習。php

time

用法 說明
time.time() 返回時間戳(從1970年1月1日00:00:00開始計算)
time.localtime() 返回當前時間的結構化時間(struct_time)對象,能夠用.tm_year等獲取年等數據
time.gmtime() 返回世界標準時間的結構化時間(struct_time)對象
time.mktime(struct_time) 結構化時間轉化爲時間戳
time.strftime("時間格式", struct_time) 結構化時間轉化爲字符串時間
time.strptime("字符串時間", "時間格式") 字符串時間轉化爲結構化時間
time.asctime([tuple]) 時間元組轉換爲字符串。若是時間元組不存在,則使用localtime()返回的當前時間
time.ctime(seconds) 將時間秒數轉換爲時間字符串,至關於time.asctime(localtime(seconds))。second不存在,則使用localtime()返回的當前時間。

經常使用時間佔位符html

  • 年 %Y
  • 月 %m
  • 日 %d
  • 時 %H (24小時制)
  • 分 %M
  • 秒 %S
  • 時分秒 %X ,至關於%H:%M:%S

time庫各方法關係
time庫各方法關係

datetime

雖然python庫中已經有了time庫,但time庫不支持對時間的加減等操做,所以就有了datetime庫。node

用法 說明
datetime.datetime.now() 獲取當前時間,返回datetime.datetime對象,有year, month, day, hour, minute, second, microsecond等屬性。
datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0 這是一個類,表示兩個 date 或者 time 的時間間隔。
datetime.datetime.fromtimestamp(seconds) 將秒數轉換爲datetime.datetime對象,datetime.datetime.fromtimestamp(time.time())<==>datetime.datetime.now()
datetime.timetuple() 這是datetime.datetime對象的方法,返回結構化時間,time.localtime() 的返回類型相同
datetime.replace(year=self.year, month=.., day=.., hour=.., minute=.., second=.., ...) 同樣是datetime.datetime對象的方法,能夠替換當前對象的year等屬性,詳見文檔

有了以上幾個方法,咱們就能夠對時間進行加減操做,並能夠在time和datetime之間進行轉換。python

  • datetime.datetime之間能夠相減,結果爲datetime.timedelta對象,有days和seconds屬性
  • datetime.datetime與datetime.timedelta之間能夠加減,結果爲datetime.datetime對象
  • datetime.timedelta自己能夠乘以一個數,以表示不一樣的時間間隔
import time
import datetime


def main():
    date1_string = "2017/6/8 15:0:0"
    # date1_string轉換爲時間戳
	# strptime -> mktime -> fromtimestamp ==> datetime.datetime
    date1 = datetime.datetime.fromtimestamp(time.mktime(
        time.strptime(date1_string, '%Y/%m/%d %H:%M:%S')))

    date2 = datetime.datetime.now()		# 獲取當前時間

    # 使用datetime.datetime對象之間 進行操做,結果爲datetime.timedelta對象
    result1 = date2 - date1		# 兩個時間過了多久了
    print(result1.days, result1.seconds)

    # datetime.datetime與datetime.timedelta之間的操做, 結果是datetime.datetime對象
    year = datetime.timedelta(days=365)     # 一年時間

    result2 = date2 + 2 * year		# 當前時間的兩年後
    print(result2.year, result2.month, result2.day)


if __name__ == '__main__':
    main()

random

使用random能夠生成僞隨機數。linux

用法 說明
random.seek(time.time()) 初始化隨機數生成器
random.random() 生成[0.0, 1.0) 範圍內的一個隨機浮點數
random.uniform(num1, num2) 返回[num1, num2] [1] 中一個隨機浮點數
random.randint(num1, num2) 生成[num1, num2] 範圍內的一個整數,num1, num2均爲int
random.randrange(num1, num2) 生成[num1, num2) 範圍內的一個整數,num1, num2均爲int
random.choice(iterable_obj) 從可迭代對象中隨機取一個元素
random.sample(iterable_obj, n) 從可迭代對象中隨機取n個元素組成一個列表返回
random.shuffle(x) 將序列 x 隨機打亂位置。不可變的能夠用random.sample(x, k=len(x))

生成驗證碼例子:git

import random


def make_code(n):
    res = ''
    for i in range(n):
        letter = chr(random.randint(65, 90))		# 生成A-Z的任意一個字母
        number = str(random.randint(0, 9))			# 生成0-9的任意一個數
        res += random.choice([letter, number])
    return res

print(make_code(9))

sys

sys模塊提供了一些與解釋器相關的變量和函數。github

用法 說明
sys.argv 返回一個列表,第一個元素是程序自己路徑,其餘元素是命令行輸入參數
sys.exit(n) 退出程序,實現方式是拋出一個SystemExit異常。正常時n爲0,非零值視爲「異常終止」。大多數系統要求該值的範圍是 0~127。
sys.path 返回模塊的搜索路徑,其本質上是列表,可使用append方法添加路徑,導入特定模塊。
sys.platform 返回平臺名稱(Linux:'linux',Windows:'win32',Mac OS X:darwin')
sys.stdout.write(" ") 不換行打印
sys.stdout.flush() 刷新

os

通常用於對文件和目錄進性操做的模塊。正則表達式

路徑相關

os.getcwd() 獲取當前工做目錄
os.chdir(path) 改變當前工做目錄算法

文件/目錄操做

用法 說明
os.mkdir(path) 建立目錄
os.makedirs(path) 遞歸建立目錄
os.redir(path) 刪除空目錄
os.removedirs(path) 遞歸刪除空目錄
os.remove(path) 刪除文件
os.rename(old_name, new_name) 更改文件或目錄名
os.stat(path) 查看文件詳情( 'st_atime', 'st_ctime', 'st_mtime', 'st_size'等)

輸出符號

用法 說明
os.sep 輸出系統分隔符(如:\/
os.linesep 輸出行終止符(win:\r\n,linux:\n)
os.pathsep 輸出路徑分割符(win:;,linux::

path

path是os庫中的一個模塊,裏面有不少實用的函數。shell

用法 說明
os.path.split(path) 把路徑分割爲(目錄, 文件名)
os.path.abspath(path) 返回path規範化的絕對路徑
os.path.normpath(path) 返回path規範化後的結果
os.path.dirname(path) split結果的個第一元素
os.path.basername(path) split結果的個第二元素
os.path.join(path1, path2, path3 ...) 把多個路徑拼接成一個,並返回
os.path.exists(path) 判斷路徑是否存在
os.path.isabs(path) 判斷路徑是否爲絕對路徑
os.path.isfile(path) 判斷路徑是否爲文件
os.path.isdir(path) 判斷路徑是否爲目錄
os.path.getatime(path) 返回文件/目錄的最後訪問時間。返回值是一個浮點數,爲紀元秒數
os.path.getctime(path) 返回文件/目錄的最後修改時間。返回值是一個浮點數,爲紀元秒數
os.path.getmtime(path) Unix:返回元數據的最後修改時間,Win:返回建立時間。返回值是一個數,爲紀元秒數
os.path.size(path) 返回文件/目錄的大小,以字節爲單位

shutil

shutil模塊提供了一系列對文件和文件集合的高階操做。 特別是提供了一些支持文件拷貝和刪除的函數。

拷貝操做

  1. shutil.copyfileobj(fsrc, fdst[, length])
    將文件類對象 fsrc 的內容拷貝到文件類對象 fdst,length表示緩衝區大小,且默認狀況爲:1024 * 1024 if WINDOWS else 64 * 1024

    import shutil
    
    
    shutil.copyfileobj(open("./t1/a.txt", "r"), open("t1/b.txt", "w"))

    注意有個fsrc是讀,而fdst是寫

  2. shutil.copyfile(src, dst)
    將src文件拷貝到dst文件,dst能夠不存在

    import shutil
    
    
    shutil.copyfile("./t1/a.txt", "./t1/b.txt")
  3. shutil.copymode(src, dst)
    僅拷貝權限。內容、組、用戶均不變,此功能並非在全部平臺上都可用(查看文檔,瞭解更多)

    import shutil
    
    
    shutil.copymode("./t1/a.txt", "./t1/b.txt")
  4. shutil.copystat(src, dst)
    從 src 拷貝權限位、最近訪問時間、最近修改時間以及旗標到 dst.

  5. shutil.copy(src, dst)
    拷貝文件和權限

  6. shutil.copy2(src, dst)
    拷貝文件和狀態信息

  7. shutil.copytree(src, dst)
    遞歸拷貝,參數不少,沒有詳細列出

    import shutil
    
    shutil.copytree('folder1', 'folder2',
    				ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    # 目標目錄不能存在,注意對folder2目錄父級目錄要有可寫權限,ignore的意思是排除

刪除操做

  • shutil.rmtree(path, ignore_errors=False, onerror=None)
    遞歸刪除文件夾。前面說過:空文件夾用os.redir(path),單個文件用os.remove(path);onerror參數能夠指定處理程序來處理異常(ignore_errors爲False時)

移動操做

  • shutil.move(src, dst)
    遞歸地將一個文件或目錄 (src) 移至另外一位置 (dst) 並返回目標位置。同一目錄時爲重命名,相似於mv命令。

json

json模塊能夠把python基本數據類型與json數據進行轉換。

  • json.dumps(data)
    將基本數據類型格式轉換爲json數據

    import json
    
    data = {
    	"name": "lczmx",
    	"age": 20,
    }
    
    s = json.dumps(data)
    
    print(repr(s))  # '{"name": "lczmx", "age": 20}'
  • json.dump(data, file_obj)
    將基本數據類型轉換爲json數據並寫入到文件中

    import json
    
    data = {
    	"name": "lczmx",
    	"age": 20,
    }
    f = open("./res.json", "w", encoding="utf-8")
    json.dump(data, f)
    
    f.close()
  • json.loads(s)
    把json字符串轉化爲python數據類型

    import json
    
    s = '{"name": "lczmx", "age": 20}'
    
    res = json.loads(s)
    
    print(res, type(res))
    # {'name': 'lczmx', 'age': 20} <class 'dict'>
  • json.load(file_obj)
    轉換文件對象的json內容。

    import json
    
    
    with open("./res.json", "r", encoding="utf-8") as f:
    	res = json.load(f)
    
    print(res, type(res))

擴展json

json模塊只支持python基本數據類型,但咱們能夠自定義JSON編碼器,重寫default方法,這樣咱們本身寫的類就可使用json.dumps

import json


class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def data_dict(self):
        # 返回的是基本數據類型
        return {"name": self.name, "age": self.age}


class JsonCustomEncoder(json.JSONEncoder):
    # 重寫default方法
    def default(self, field):
        if isinstance(field, Foo):
            return field.data_dict()    # 調用自定義的方法
        else:
            return json.JSONEncoder.default(self, field)


f = Foo("lczmx", 21)

# 使用時要指定自定義的編碼器
res = json.dumps(f, cls=JsonCustomEncoder)
print(res)
# {"name": "lczmx", "age": 21}

pickle

模塊 pickle 實現了對一個 Python 對象結構的二進制序列化和反序列化。它只能用於Python,而且可能不一樣版本的Python彼此都不兼容,所以,只能用Pickle保存那些不重要的數據,不能成功地反序列化也不要緊。

注意:pickle 模塊並不安全。你只應該對你信任的數據進行unpickle操做.

import pickle

dic = {'name': 'alvin', 'age': 23, 'sex': 'male'}

print(type(dic))  # <class 'dict'>

j = pickle.dumps(dic)
print(type(j))  # <class 'bytes'>


f = open('序列化對象_pickle', 'wb')  # 注意是w是寫入str,wb是寫入bytes,j是'bytes'
f.write(j)  # -------------------等價於pickle.dump(dic,f)

f.close()
# -------------------------反序列化
f = open('序列化對象_pickle', 'rb')

data = pickle.loads(f.read())  # 等價於data=pickle.load(f)


print(data['age'])

shelve

shelve" 是一種持久化的相似字典的對象,只有open方法,比pickle簡單。
因爲 shelve 模塊須要 pickle 的支持,因此shelve模塊也不安全。須要注意是否爲信任數據才能使用。

import shelve

d = shelve.open("持久化文件.txt")


# 以 d[key] = data 的形式存儲
d["name"] = "lczmx"
d["age"] = 22
d["addr"] = "guangzhou"
d["data"] = [1, 2, 3]


# 使用中括號取值
name = d["name"]
print(name)         # lczmx

# 使用del刪除某個鍵對應的值

del d["age"]

# 可使用 in 判斷某個鍵是否存在
flag = "age" in d
print(flag)         # False

# .keys()方法 能夠列出全部的鍵 (速度較慢!)
klist = list(d.keys())
print(klist)        # ['name', 'addr', 'data']


# 值即便是引用對象,假如要保存修改後的值,要從新賦值
temp = d['data']
temp.append(4)
print(d["data"])    # [1, 2, 3]
d['data'] = temp
print(d["data"])    # [1, 2, 3, 4]

# close掉,可使用上下文管理協議
d.close()

xml

xml也是一個能夠跨語言的數據交換協議,但使用起來沒有json簡單,因爲xml誕生的時間比json早,因此至今還有一些公司正在使用。

生成xml

步驟:

  1. 建立根節點
  2. 爲根節點添加子節點
  3. 爲字節點添加內容和屬性
  4. 生成文檔對象樹
  5. 保存到文件等
import xml.etree.ElementTree as ET

# 建立根節點
new_xml = ET.Element("namelist")

# 爲跟節點建立字節點
name1 = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})
age1 = ET.SubElement(name1, "age", attrib={"checked": "no"})

# 添加內容
name1.text = '老王'
age1.text = "30"

# 同上
name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
age2 = ET.SubElement(name2, "age")
name2.text = "隔壁"
age2.text = '33'

# 生成文檔對象
et = ET.ElementTree(new_xml)

# 寫入文件中
et.write("test.xml", encoding="utf-8", xml_declaration=True)

# 打印生成的格式
ET.dump(new_xml)

結果:

<?xml version='1.0' encoding='utf-8'?>
<namelist>
    <name enrolled="yes">老王<age checked="no">30</age></name>
    <name enrolled="no">隔壁<age>33</age></name>
</namelist>

讀取xml

對xml文件進行操做,用的是parse方法和getroot方法

import xml.etree.ElementTree as ET


tree = ET.parse("./test.xml")
root = tree.getroot()

如下都以root即根節點這個對象進行操做
root能夠換成任意子節點

查看

  • root.tag 獲取標籤名
  • root.attrib 獲取屬性
  • root.text 獲取內容

遍歷/查找

  • root.iter(tag) 查找子孫節點中的tag標籤,以迭代器方式返回
  • root.find(tag) 查找子節點的第一個tag標籤
  • root.findall(tag) 找子節點的全部tag標籤

修改

  • root.text="xx" 修改內容
  • root.set("屬性名", "屬性值") 設置屬性值

刪除

  • root.remove(node) 刪除子節點

struct

此模塊能夠執行 Python 值和以 Python bytes 對象表示的 C 結構之間的轉換。 這能夠被用來處理存儲在文件中或是從網絡鏈接等其餘來源獲取的二進制數據。
通常使用它的兩個函數:

  1. struct.pack("格式", data)
  2. struct.unpack("格式", byte_data)
import struct


# 數據 -> bytes
pi = 3.14159265358
res = struct.pack("f", pi)
print(res, type(res))  # b'\xdb\x0fI@' <class 'bytes'> # 已經轉化爲字節類型


# bytes -> 原數據
data = struct.unpack("f", res)
print(data, type(data))  # (3.1415927410125732,) <class 'tuple'>
格式 C 類型 Python 類型 標準大小 註釋
x 填充字節
c char 長度爲 1 的字節串 1
b signed char 整數 1 (1), (2)
B unsigned char 整數 1 (2)
? _Bool bool 1 (1)
h short 整數 2 (2)
H unsigned short 整數 2 (2)
i int 整數 4 (2)
I unsigned int 整數 4 (2)
l long 整數 4 (2)
L unsigned long 整數 4 (2)
q long long 整數 8 (2)
Q unsigned long long 整數 8 (2)
n ssize_t 整數 (3)
N size_t 整數 (3)
e (6) 浮點數 2 (4)
f float 浮點數 4 (4)
d double 浮點數 8 (4)
s char[] 字節串
p char[] 字節串
P void * 整數 (5)

re

正則表達式是用來描述字符或字符串的特殊符號,在python中用re模塊實現,正則表達式模式被編譯成一系列的字節碼,用 C 編寫的匹配引擎執行。

元字符

正則表達式語言由兩種基本字符類型組成:原義(正常)文本字符和元字符,元字符實質上就是有特殊含義的字符。
下面列舉一些經常使用的元字符,參考文檔給出的元字符

字符 描述 列子
\\ 匹配\
\w 匹配字母、數字、下劃線
\W 匹配非字母數字下劃線
\s 匹配空白字符
\S 匹配非空白字符
\d 匹配數字
\D 匹配非數字
\n 匹配換行符
\t 匹配製表符
^ 匹配字符串的開頭
$ 匹配字符串的結尾
. 匹配除換行符外的全部字符,當re.DOTALL標記被指定時,能夠匹配換行符
[] 匹配括號中的每個字符,如[abc]表示abc
[^] 匹配不在括號中的字符,如[^abc]表示不是ab
* 對它前面的正則式匹配0到任意次重複,如\w*表示0到任意個數字
+ 對它前面的正則式匹配1到任意次重複
? 對它前面的正則式匹配0到1次重複
{n} 對其以前的正則式指定匹配 m 個重複;少於 m 的話就會致使匹配失敗,如\w{6}表示6個數字
{n,m} 對正則式進行 n 到 m 次匹配,在 n 和 m 之間取儘可能多。
a|b 匹配a或b
() 組合,匹配括號內的表達式

更多能夠看這篇文章 linux shell 正則表達式(BREs,EREs,PREs)差別比較
關於(?…)個擴展標記法,能夠看官方文檔。

方法

查找

使用 說明
re.findall(pattern, string) 匹配全部結果,返回一個列表,空匹配也會包含在結果裏
re.finditer(pattern, string) 匹配全部結果,返回由匹配對象(re.Match)構成的迭代器 。 string 從左到右掃描,匹配按順序排列。空匹配也包含在結果裏。
re.search(pattern, string) 匹配第一個結果,返回匹配對象(re.Match),未匹配到時爲None
re.match(pattern, string) 字符串開頭至關於re.search("^ ...", string)是否匹配pattern,是則返回匹配對象(re.Match),未匹配到時爲None

分割

  • re.split(pattern, string, maxsplit=0, flags=0)
    以pattern規則分割string,結果以列表形式返回,maxsplit非零時,表示分割多少次,flags=re.IGNORECASE能夠忽略大小寫
    import re
    
    
    s = "12a21v13xsa15"
    res = re.split("[a-z]+", s)
    
    print(res)      # ['12', '21', '13', '15']

替換

  • re.sub(pattern, repl, string, count=0, flags=0)
    返回經過使用 repl 替換在 string 最左邊非重疊出現的 pattern 而得到的字符串。
    可選參數 count 是要替換的最大次數;count 必須是非負整數。若是省略這個參數或設爲 0,全部的匹配都會被替換。
    import re
    
    s = "12a21v13xsa15"
    res = re.sub("[a-z]+", ", ", s)
    
    print(res)  # 12, 21, 13, 15
    假如repl參數是一個函數,那麼能夠極大擴展替換功能。
    import re
    
    
    s = "name=lczmx, age=22"
    
    
    def repl_func(matchobj):
    	age = int(matchobj.group("age"))
    	return str(age + 1)
    
    
    res = re.sub(r"(?P<age>\d+)", repl_func, s)
    print(res)      # name=lczmx, age=23

匹配對象(re.Match)操做

  • Match.group([group1, ...])
    返回一個或者多個匹配的子組。若是隻有一個參數,結果就是一個字符串,若是有多個參數,結果就是一個元組,使用正則表達式使用了(?P<name>…) 語法,能夠用Match.group("name")的方式取值。
  • Match.groups(default=None)
    返回一個元組,包含全部匹配的子組
  • Match.groupdict(default=None)¶
    返回一個字典,包含了全部的命名子組。key就是組名
    import re
    
    s = "abc@example.com,user"
    
    res = re.match(r"([a-zA-Z]+)@(\w+\.com)", s)
    
    
    print(res.groups())  # ('abc', 'example.com')
    print(res.group(0))  # abc@example.com
    print(res.group(1))  # abc
    print(res.group(2))  # example.com
    
    
    res = re.match(r"(?P<prefix>\w+)@(?P<suffix>\w+\.com)", s)
    
    print(res.groups())  # ('abc', 'example.com')
    print(res.group(0))  # abc@example.com
    
    print(res.group(1))  # abc
    print(res.group("prefix"))  # abc
    
    print(res.group(2))  # example.com
    print(res.group("suffix"))  # example.com
    
    print(res.groupdict())  # {'prefix': 'abc', 'suffix': 'example.com'}

去括號優先級
假如這樣的例子:

import re


res = re.findall(r"(abc)+", "abcabcabc")
print(res)      # ['abc']

其匹配結果是["abc"],而非["abcabcabc"],這是由於括號的優先級高,假如要括號與後面的元字符相結合的化可使用如下方法:

import re


res = re.findall(r"(?:abc)+", "abcabcabc")
print(res)      # ['abcabcabc']

匹配原理
關於正則匹配原理,看此文

logging

關於日誌管理的基本教程,請點擊這裏

關於使用日誌的流程,大約有如下步驟:

  1. 調用logging.basicConfig()設置logging,肯定日記級別、是否輸入到文件、信息格式等參數
  2. 根據需求,調用loggingdebuginfowarningerrorcritical方法

注意
因爲logging.basicConfig()只須要定義一次,因此debug等方法應該在其被設置後調用

打印到終端

打印到終端是開發過程當中的一個實用的方法。

import logging


logging.basicConfig()

logging.debug("debug messages")
logging.info("info messages")
logging.warning("warning messages")
logging.error("error messages")
logging.critical("critical messages")

因爲默認日誌級別爲WARNING,因此只在終端顯示了後三行信息

寫入文件

basicConfig()增長filename參數便可

import logging


logging.basicConfig(filename="test.log")

logging.debug("debug messages")
logging.info("info messages")
logging.warning("warning messages")
logging.error("error messages")
logging.critical("critical messages")

python 3.9版本的logging.basicConfig() 能夠指定encoding參數,以前的以系統默認的編碼方式打開。

多模塊使用

在多個模塊中import logging便可,其操做的是同一個logging對象

import logging
import mylib


def main():

    logging.basicConfig()
    logging.warning("start function")
    mylib.my_func()
    logging.warning("end function")
    print(id(logging))	# 2248755624272


if __name__ == '__main__':
    main()

./mylib.py

# ./mylib.py
import logging


def my_func():
    logging.error("error massage")
    print(id(logging))	# 2248755624272

修改日誌級別

日誌級別從低到高:

級別 什麼時候使用
DEBUG 細節信息,僅當診斷問題時適用。
INFO 確認程序按預期運行
WARNING 代表有已經或即將發生的意外(例如:磁盤空間不足)。程序仍按預期進行
ERROR 因爲嚴重的問題,程序的某些功能已經不能正常執行
CRITICAL 嚴重的錯誤,代表程序已不能繼續執行

默認級別爲WARNING

修改日誌級別要用到logging.basicConfig()level參數,其傳入的值是一個在logging模塊中已經被定義好的數:

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

例子:

import logging


logging.basicConfig(level=logging.INFO)
logging.warning("start function")

從命令行中接收日誌級別

使用argparse庫接收命令行參數,再使用getattr()方法從logging模塊中把對應的日誌級別取出來:

import logging
import argparse

# log選項的值只能是level_list的元素
level_list = ["debug", "info", "warning", "warn", "error", "fatal", "critical"]
level_list.extend(list(map(lambda x: x.upper(), level_list)))	# 全大寫再加入

parser = argparse.ArgumentParser(description="test file")

parser.add_argument("--log", default="debug", choices=level_list)

args = parser.parse_args()

# 拿到級別字符串後要大寫

level = getattr(logging, args.log.upper())
logging.basicConfig(level=level)

logging.debug("debug messages")
logging.info("info messages")
logging.warning("warning messages")
logging.error("error messages")
logging.critical("critical messages")
$ python test.py --log error
ERROR:root:error messages
CRITICAL:root:critical messages

$ python test.py --log info 
INFO:root:info messages
WARNING:root:warning messages
ERROR:root:error messages
CRITICAL:root:critical messages

configparser

configparser庫是python的配置文件管理模塊,其所用結構與 INI 文件的相似。
注意:小節(section)中的鍵(key)大小寫不敏感而且會存儲爲小寫形式

步驟:

  1. 建立對象configparser.ConfigParser()
  2. 在字典中添加數據,用中括號操做,相似字典
  3. 寫入文件
import configparser

# 1 建立parser對象
config = configparser.ConfigParser()

# 2 添加數據
# 方法一
config["DEFAULT"] = {"HOST": "localhost", "PORT": "3306"}

# 方法二
config["CUSTOM"] = {}
config["CUSTOM"]["HOST"] = "192.168.0.1"
# 或
custom_config = config["CUSTOM"]
custom_config["PORT"] = "3333"

# 3 寫入文件

with open("config.ini", "w") as f:
    config.write(f)

最外層就是一個字典

config.ini文件:

[DEFAULT]
host = localhost
port = 3306
 [CUSTOM]
host = 192.168.0.1
port = 3333

注意:DEFAULT不在sections()中,能夠直接用["DEFAULT"].get(key).get("DEFAULT", key)取值
根據不一樣的需求能夠用如下幾個方法:

  • config.read(path) 讀取配置文件

  • config.sections() 返回可用節的列表,即[xxx]中的xxx

  • config.options(Section) 返回鍵構成的元組

  • config.items(Section) 返回列表,元素爲鍵值對組成的元組

  • config.get(Section, key) 等價於 Section.get(key)

  • Section.get(key, default) 相似字典同樣取值

    config 還能夠經過使用for循環,有.keys(), .values(), .items()

    import configparser
    
    config = configparser.ConfigParser()
    
    config.read("./config.ini")
    
    print(config["DEFAULT"].get("host"))    # localhost
    
    print(config.options("CUSTOM"))  # ['host', 'port']
    
    print(config.items("CUSTOM"))
    # [('host', '192.168.0.1'), ('port', '3333')]

刪操做

  • config.remove_section(section) 刪除塊即整個[xxx]

  • config.remove_option(section, key) 刪除塊下面的鍵(包括值)

    import configparser
    
    config = configparser.ConfigParser()
    
    config.read("./config.ini")
    
    config.remove_section("CUSTOM")
    config.remove_option("DEFAULT", "host")
    config.write(open("./config.ini", "w"))

argparse

argparse是python推薦的命令行參數解析模塊,argparse基於optparse(3.2版中已經被棄用),因此二者用法相似。
其通常的使用步驟是:

  1. 建立解析器
  2. 添加參數
  3. 解析參數

建立解析器

parser = argparse.ArgumentParser(description="計算兩個數的和", prog="SUM")
  • description參數能夠指定幫助文檔以前顯示的描述信息
  • prog 指定程序名,默認sys.argv[0]

添加參數

使用parser.add_argument(name or flags)方法,該方法能夠指定位置參數或者是選項,並且它能夠接收不少參數,下面列舉幾個經常使用的參數:

  • action - 當參數在命令行中出現時使用的動做基本類型。
    它的值列出這幾個更多能夠看文檔
    action值 說明
    store 存儲參數的值(默認)
    store_true and store_false 分別用做存儲 True 和 False 值的特殊用例
    version 指望有一個 version= 命名參數,version參數能夠用%(prog)s的形式使用prog參數
  • default - 設置默認值。
  • type - 命令行參數應當被轉換成的類型,即把str轉成其餘形式。
  • choices - 可用的參數的容器(通常爲列表),即參數值只能是裏面的元素。
  • required - 此命令行選項是否必需,默認False
    (通常來講選項是能夠被省略的,否則換爲位置參數更好)。
  • help - 爲此選項做用的簡單描述,使用-h或--help能夠看到。
parser.add_argument("x", type=float, help="一個數x")        # 添加位置參數x
parser.add_argument("y", type=float, help="一個數y")        # 添加位置參數y
# 添加選項-a, 把值存儲爲True
parser.add_argument("-a", action="store_true", help="顯示詳細過程")

# 添加選項-f,它的值知道能是[1, 2, 3]中的元素
parser.add_argument("-f", default=1, choices=[1, 2, 3],
                    type=int, help="保留小數點位數")

# 添加選項-v 或 --version
# 使用來自argparse.ArgumentParser的prog參數
parser.add_argument("-v", "--version", action="version",
                    version="%(prog)s 0.1", help="顯示版本")

解析參數

經過parser.parse_args()解析,而後經過.的方式取值(不管位置參數仍是選項)

# 解析
args = parser.parse_args()
print(args.x)
print(args.a)
print(args.f)

完整例子

一個計算兩個數和的程序

import argparse

parser = argparse.ArgumentParser(description="計算兩個數的和", prog="SUM")

parser.add_argument("x", type=float, help="一個數x")        # 添加位置參數x
parser.add_argument("y", type=float, help="一個數y")        # 添加位置參數y
# 添加選項-a, 把值存儲爲True
parser.add_argument("-a", action="store_true", help="顯示詳細過程")

# 添加選項-f,它的值知道能是[1, 2, 3]中的元素
parser.add_argument("-f", default=1, choices=[1, 2, 3],
                    type=int, help="保留小數點位數")

# 添加選項-v 或 --version
# 使用來自argparse.ArgumentParser的prog參數
parser.add_argument("-v", "--version", action="version",
                    version="%(prog)s 0.1", help="顯示版本")

# 解析
args = parser.parse_args()

# 計算並保留小數
res = round(args.x + args.y, args.f)

if args.a:
    print("{x} + {y} = {res}".format(x=args.x, y=args.y, res=res))
else:
    print(res)

在命令行中使用:

$ python get_sum.py -h
usage: SUM [-h] [-a] [-f {1,2,3}] [-v] x y

計算兩個數的和

positional arguments:
  x              一個數x
  y              一個數y

optional arguments:
  -h, --help     show this help message and exit
  -a             顯示詳細過程
  -f {1,2,3}     保留小數點位數
  -v, --version  顯示版本


$ python get_sum.py -v
SUM 0.1


$ python get_sum.py 3.14 5.96
9.1

$ python get_sum.py 3.14 5.96 -a
3.14 + 5.96 = 9.1

$ python get_sum.py 3.14159 3.335 -f 3 -a 
3.14159 + 3.335 = 6.477

$ python get_sum.py 
usage: SUM [-h] [-a] [-f {1,2,3}] [-v] x y
SUM: error: the following arguments are required: x, y

hashlib

hashlib是針對不一樣的安全哈希和消息摘要算法實現了一個通用的接口。

生成md5

import hashlib


md5 = hashlib.md5()
# 輸入的是字節串
md5.update("test message".encode("utf-8"))

res = md5.hexdigest()
print(res)
# c72b9698fa1927e1dd12d3cf26ed84b2

爲md5加鹽
所謂加鹽就是update其餘內容,改變md5的值,防止撞庫。

import hashlib


md5 = hashlib.md5()
# 輸入的是字節
md5.update("加鹽".encode("utf-8"))
md5.update("test message".encode("utf-8"))

res = md5.hexdigest()
print(res)
# 3f5a030db81d9e5e83d2c8e7eba1965c

uuid

生成uuid4

import uuid

print(uuid.uuid4())
# f1d50cdd-2f36-4db2-b788-ec4f2f08ce52

subprocess

subprocess 模塊容許你生成新的進程,鏈接它們的輸入、輸出、錯誤管道,而且獲取它們的返回碼。
對於subprocess模塊,咱們只須要關注底層的Popen接口的使用方法便可。
經常使用參數:

  • args
    通常來講是命令,推薦使用列表的方式傳入(有順序)
  • shell
    True或False
    在 POSIX,當 shell=True, shell 默認爲 /bin/sh
    在 Windows,當 shell=True,環境變量 COMSPEC 指定了默認 shell,執行命令時能夠爲True,但執行批處理文件或可執行文件時,不須要shell=True
  • stdinstdoutstderr
    分別指定了執行的程序的標準輸入、輸出和標準錯誤文件句柄
    它們的合法值通常有:
    1. 其餘Popen對象的stdin/stdout/stderr
    2. subprocess.PIPE 表示打開標準流的管道
    3. None
    4. 文件對象

更加詳細內容,請看官方文檔

獲取返回信息

  1. 使用subprocess.PIPE接收
  2. popen_obj.stdout.read().decode("xx") 的方式

固然也能夠在stdout中傳入文件對象,直接寫入文件中

使用例子

import subprocess


# 執行沒有參數的
subprocess.Popen(["dir"], shell=True, stdout=open("dir_res.txt", "w"))


# 有參數
# get_sum.py爲argparse模塊最後的例子
command = "python get_sum.py 3.47 2.48 -a -f 2"

res2 = subprocess.Popen(command.split(" "), shell=True, stdout=subprocess.PIPE)
print(res2.stdout.read().decode("gbk"))  # 3.47 + 2.48 = 5.95


# stdout做爲stdin

res3 = subprocess.Popen(["echo", "www.baidu.com"],
                        shell=True, stdout=subprocess.PIPE)

res4 = subprocess.Popen(["nslookup"], shell=True,
                        stdin=res3.stdout, stdout=subprocess.PIPE)

print(res4.stdout.read().decode("gbk"))
""" 默認服務器: UnKnown Address: 192.168.0.1 > 服務器: UnKnown Address: 192.168.0.1 名稱: www.baidu.com Address: 182.61.200.7 > """

個人github
個人博客
個人筆記


  1. num1 > num2時爲[num2, num1]

相關文章
相關標籤/搜索