1,time
時間的表示形式:
- 格式化的字符串:'2018-2-4 14:08:01'
- 時間戳:1970年1月1日至今經歷的秒數
- 元組(struct_time):time.struct_time(tm_year=2018, tm_mon=2, tm_mday=4, tm_hour=10, tm_min=34, tm_sec=56, tm_wday=6, tm_yday=35, tm_isdst=0
time模塊方法:
- time():獲取本地時間戳
- gmtime(secondes):UTC時間戳 —> 元組,缺省為當前時間
- localtime(seconds):本地時間戳 —> 元組,缺省為當前時間
- mktime(tupple):元組 —> 時間戳
- strftime(format[,tupple]):元組 —> 字符串,例如time.strftime("%Y-%m-%d %H-%M-%S") ,不輸入tupple是本地時間
- strptime(string, format):字符串 —> 元組,例如time.strptime(%H-%M-%S", "%Y-%m-%d"),不輸入tupple是本地時間
- asctime([tupple]):元組 —> 字符串,是sat aug 20 15:01:42 2016這種格式
- ctime(seconds):時間戳 —> 字符串,是sat aug 20 15:01:42 2016這種格式
- sleep():略
舉例,改時間戳,計算2個時間點相差了多少個小時:
def timeformat(item): # 改時間戳 local_timeArray = time.strptime(item, "%Y-%m-%d %H:%M:%S") local_timeStamp = int(time.mktime(local_timeArray)) return round(float(local_timeStamp)/3600, 2) # 對時間戳換算到小時並保留2位 >>> t1 = timeformat('2019-3-27 18:20:01') >>> t1 431578.33 >>> t2 = timeformat('2019-3-29 6:10:20') >>> t2 431614.17 >>> t2 - t1 35.839999999967404 # t2減去t1,相差35.84個小時
datatime:time的高級封裝,包括date類,time類,datetime類
datetime.datetime.now() + datetime.timedetla(3) # 當前時間+3天 datetime.datetime.now() + datetime.timedetla(hours=3) # 當前時間+3個小時
2,random
- random.random() # 0到1之間的隨機浮點數
- random.uniform(1, 10) # 1到10之間的隨機浮點數,相比較random增加了區間功能
- random.randint(1, 8) # 1到8之間的隨機整數,范圍是[1,8],包括1和8
- random.randrange(1,8) # 1到8之間的隨機整數,范圍是[1,7],包括1,但不包括8,和range一樣,顧頭不顧尾
- random.choice('hello') # 從傳入的序列中隨機取值,可以傳字符串、列表元組等
- random.sample('hello', 2) # 從傳入的序列中隨機取2個值
- random.shuffle(list) # 把傳入的list的序列打亂
舉例,生成偽隨機驗證碼:
import random checkcode = '' # 4位數字 for i in range(4): current = random.randint(1,9) checkcode += str(current) print(checkcode) checkcode = '' # 4位數字或大寫字母 for i in range(4): current = random.randint(0,3) if current == i: tmp = chr(random.randint(65, 90)) else: tmp = random.randint(0, 9) checkcode += str(tmp) print(checkcode)
3,os
- os.getcwd() # 獲取當前工作目錄
- os.listdir(path) # 列出指定目錄下的所有文件和f子目錄,包括隱藏文件。listdir不會遍歷子目錄,但os.walk會遍歷子目錄。
>>> os.listdir(os.getcwd()) # 獲取執行腳本所在文件下的全部內容
- os.walk(path) # 遍歷目錄,返回generator,三元組:當前路徑,當前路徑下的文件夾列表,當前路徑下的文件列表
- os.chdir("dirname") # 改變當前腳本工作目錄;相當於shell下cd,注意切換目錄時需要轉移,方法一用'/',方法二前面加'r'
- os.curdir # 返回當前目錄: ('.')
- os.pardir # 獲取當前目錄的父目錄字符串名:('..')
- os.mkdir('dirname') # 生成單級目錄;相當於shell中mkdir dirname
- os.makedirs('dirname1/dirname2') # 可生成多層遞歸目錄,例如:os.mkdirs(r'd:\a\b\c\d')
- os.rmdir('dirname') # 刪除單級空目錄,若目錄不為空則無法刪除,報錯;相當於shell中rmdir dirname,清理單個空文件夾
- os.removedirs('dirname1') # 若目錄為空,則刪除,並遞歸到上一級目錄,如若也為空,則刪除,依此類推,清理遞歸空文件夾
- os.remove() # 刪除一個文件
- os.rename("oldname","newname") # 重命名文件/目錄
- os.stat('path/filename') # 獲取文件/目錄信息,atime存儲時間,mtime修改時間,大小等等
- os.sep # 輸出操作系統特定的路徑分隔符,win下為"\\",Linux下為"/"
- os.linesep # 輸出當前平台使用的行終止符,win下為"\t\n",Linux下為"\n"
- os.pathsep # 輸出用於分割文件路徑的字符串
- os.name # 輸出字符串指示當前使用平台。win->'nt'; Linux->'posix'
- os.system("bash command") # 運行linux的shell命令,windows的cmd命令
- os.environ # 獲取系統環境變量,返回的是所有環境變量,sys.path返回的是python相關的環境變量
- os.get_terminal_size() # 獲取終端大小
os.path
- os.path.dirname(pah):返回path的目錄名
- os.path.basename(path):返回path的文件名
- os.path.split(path):返回路徑 + 文件/文件名
- os.path.splitext(path):返回路徑 + 后綴
- os.path.exists(path):是否存在
- os.path.isfile(path):是否文件
- os.path.isdir(path):是否目錄
- os.path.islink(path):是否link
- os.path.isabs(path):是否絕對路徑
- os.path.realpath(path):link對應的真實路徑
- os.path.listdir(path):獲取path下的目錄 + 文件列表
- os.path.abspath(path) :返回path規范化的絕對路徑
- os.path.join(path1[, path2[, ...]]):將多個路徑組合后返回,第一個絕對路徑之前的參數將被忽略
- os.path.size(path):獲取大小
- os.path.getmtime(path):最后修改時間
- os.path.getatime(path):最后存取時間
4,sys
- sys.argv # 是傳給腳本的參數,是一個list,python abc.py 1 2 3,sys.argv就是[abc.py, 1, 2, 3]
- sys.exit(n) # 退出程序,正常退出時exit(0)
- sys.version # 獲取Python解釋程序的版本信息
- sys.maxint # 最大的Int值
- sys.path # 返回模塊的絕對路徑,初始化時使用PYTHONPATH環境變量的值
- sys.platform # 返回操作系統平台名稱
- sys.stdout.write() 和 sys.stdout.flush() # print('abc') 等效於 sys.stdout.write('abc\n')
終止程序並顯示錯誤:
raise SystemExit('it falied')
5,shutil
copy文件,壓縮文件、拷貝目錄、刪除目錄等,shutil壓縮功能是通過調用zipfile和tarfile這2個模塊實現的
- shutil.copyfileobj(src, dst) # 需要自己open
- shutil.copyfile(src, dst) # 無需自己open,只拷貝文件
- shutil.copy(src, dst) # 同時拷貝文件和權限
- shutil.copy2(src, dst) # 拷貝文件保留元數據
- shutil.copytree(src, dst) # 拷貝目錄,如果想保留符號鏈接,可以設置Symlinks=True
- shutil.move(src, dst) # 移動文件
- shutil.copymode
- shutil.copystat # 拷貝狀態信息
- shutil.make_archive() # 壓縮
- shutil.unpack_archive() # 解壓縮
6,json,pickle,shelve,PyYAML,ConfigParser,xml.etree.ElementTree
處理json,序列化,反序列化,配置文件
常見配置文件:
適合人類編寫:ini > toml > yaml > json > xml > plist
可以存儲的數據復雜度:xml > yaml > toml ~ json ~ plist > ini
json:所有語言之間交互,但只能傳字典
pickle:python內部交互,可以傳所有內容
shelve:pickle更上一層封裝
PyYAML:處理yaml配置文件
ConfigParser:處理ini配置文件
xml.etree.ElementTree:處理xml文件
序列化舉例,字典到文件的讀寫:
方法一:str + eval
f.write(str(dict)) # 轉成str存,即序列化 eval(str(dict)) # 用eval讀,即反序列化
方法二:json
# dumps序列化: f.write(json.dumps(info)) json.dump(info, f) # loads反序列化: json.loads(f.read()) json.load(f)
方法三:pickle,參照json
json不支持函數序列化,pickle支持函數的序列化
json可以跨語言,pickle只能python內部
注意:json和pickle,python3只能dump和load一次
7,paramiko
SSH登錄
9,itertools
9.1,過濾
def screen(val): return True if val > 0 else False ls = [3, 1, -5, 2, 3, -9, 10]
filter(fun, it): 將it中的元素i逐個傳給fun,如果fun(i)為真值,name產出對應的i。
>>> list(filter(screen, ls)) [3, 1, 2, 3, 10]
itertools.filterfalse(fun, it):與filter功能相反
>>> list(itertools.filterfalse(screen, ls)) [-5, -9]
itertools.compress(it, it_ref):並行迭代it和it_ref,如果it_ref中的值為真值,產出it中對應的值,返回的是iterable
>>> list(itertools.compress('abcd', [1, 0, 1, 0])) ['a', 'c']
itertools.dropwhile(fun, it):跳過開頭幾個匹配為True的,后面不再匹配
list(itertools.dropwhile(screen, ls)) [-5, 2, 3, -9, 10] # 后面再碰到返回True的2不再跳過了
itertools.takewhile(fun, it):產出相當於dropwhile丟掉的幾個值,takewhile + dropwhile = it
>>> list(itertools.takewhile(screen, ls)) [3, 1]
itertools.islice(it, start, stop, step):切片,it可以是任何iterable,start可選默認=0,step可選默認=1,注意:迭代器由於沒有getitem沒法使用普通切片函數,islice會消耗掉迭代器中的數據。如果stop=None,表示無限大,結合start值可以用來跳過前幾個元素。
def count(n): while True: yield n n += 1 c = count(1) >>> list(itertools.islice(c, 10, 20, 2)) [11, 13, 15, 17, 19] >>> list(itertools.islice(c, 10, 15)) [11, 12, 13, 14, 15] >>> list(itertools.islice(c, 5)) [1, 2, 3, 4, 5]
9.2,映射
enumerate(it, start=0) :索引 + value
>>> list(enumerate('abcde', 1)) [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')]
map(fun, it1[it2, it3, ... itN]):將it中的元素傳給fun,產出元素
>>> list(map(lambda x, y: x + y, [1, 2, 3], [1, 1, 1])) [2, 3, 4]
itertools.accumulate(it, [fun]):產出列表,不斷將it傳給后面的函數,產出結果,如果沒有函數,產出累加
>>> list(itertools.accumulate([1, 3, 2, 4])) [1, 4, 6, 10] >>> list(itertools.accumulate([1, 3, 2, 4], operator.mul)) [1, 3, 6, 24]
itertools.startmap(fun, it):獲取it中的元素,傳給fun執行
>>> list(itertools.starmap(operator.mul, enumerate('abcde', 1))) ['a', 'bb', 'ccc', 'dddd', 'eeeee']
9.3,容器合並
zip(it1, it2, ..., itN):從多個可迭代對象中獲取元素
>>> list(zip('abc', range(4))) [('a', 0), ('b', 1), ('c', 2)]
itertools.zip_longst(it1, ...itN, fillvalue=None):zip的longst版
>>> list(itertools.zip_longest('abc', range(4), fillvalue='#')) [('a', 0), ('b', 1), ('c', 2), ('#', 3)]
itertools.product(it1, ...itN, repeat=1):計算笛卡爾積,矩陣展開,可以多個省略for循環語句
>>> list(itertools.product('abc', range(2), repeat=1)) [('a', 0), ('a', 1), ('b', 0), ('b', 1), ('c', 0), ('c', 1)]
itertools.chain(it1, it2,..., itN):依次迭代多個容器,可以是不同類型的容器,省空間不會產生新序列。heapq.merge()也可以迭代多個不同容器,但元素需要相同類型。
>>> list(itertools.chain('abc', range(2), ('c', 'd')) ['a', 'b', 'c', 0, 1, 'c', 'd']
itertools.chain.from_iterable(it) : 和chain差不多, 從嵌套的容器中獲取元素,只是將不同容器放在一個iterable中
>>> list(itertools.chain.from_iterable(['abc', range(2), ('c', 'd')])) ['a', 'b', 'c', 0, 1, 'c', 'd']
9.4,輸入—>輸出n
itertools.combinations(it, n):前n元素的組合,不重復
>>> list(itertools.combinations('abc', 2)) [('a', 'b'), ('a', 'c'), ('b', 'c')]
itertools.combinations_with_replacement(it, n):前n元素的組合,可重復
>>> list(itertools.combinations_with_replacement('abc', 2)) [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]
itertools.permutations(it, n=None):前n元素的排列
>>> list(itertools.permutations('abc', 2)) [('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')]
itertools.count(start=0, step=1):無限產出值,默認從0開始,步長為1
itertools.repeat(item, [n]):產出n次item,不提供參數n則無限產出
itertools.cycle(it):從it中無限循環產出值
9.5,重排
reversed(seq):反向遍歷
itertools.groupby(it, key=None):分組產出iterable,key是分組標准,使用前必須先根據分組標准排序
# 根據首字母分組: l = ['apple', 'dark', 'china', 'apache', 'cry', 'department','cycle'] l.sort(key=lambda i: i[0]) # 必須先排序 for first_letter, group in itertools.groupby(l, key=lambda i: i[0]): print(first_letter, list(group)) # 輸出為: a ['apple', 'apache'] c ['china', 'cry', 'cycle'] d ['dark', 'department']
# 根據單詞字母數量分組: l = ['apple', 'dark', 'china', 'apache', 'crazy', 'depart', 'cycle'] l.sort(key=len) # 必須先排序 for first_letter, group in itertools.groupby(l, key=len): print(first_letter, list(group)) # 輸出為: 4 ['dark'] 5 ['apple', 'china', 'crazy', 'cycle'] 6 ['apache', 'depart'
# 字典列表中,根據根據x的value的首字母進行分組: rows = [{'x': 'apple', 'y': 'a'}, {'x': 'dark', 'y': 'b'}, {'x': 'china', 'y': 'a'}, {'x': 'apache', 'y': 'a'}, {'x': 'cry', 'y': 'c'}, {'x': 'department', 'y': 'a'}, {'x': 'cycle', 'y': 'b'}] rows.sort(key=itemgetter('x')) for i, t in groupby(rows, key=lambda i: itemgetter('x')(i)[0]): print(i) for j in t: print(j) # 輸出為: a {'x': 'apache', 'y': 'a'} {'x': 'apple', 'y': 'a'} c {'x': 'china', 'y': 'a'} {'x': 'cry', 'y': 'c'} {'x': 'cycle', 'y': 'b'} d {'x': 'dark', 'y': 'b'} {'x': 'department', 'y': 'a'}
itertools.tee(it, n=2):產出n個相同的it
>>> t = itertools.tee(iter(range(5)), 2) >>> list(t[0]) [0, 1, 2, 3, 4] >>> list(t[1]) [0, 1, 2, 3, 4]
10,collections
collections的所有方法:['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 'UserString', 'Counter', 'OrderedDict', 'ChainMap'],詳見collections/__init__.py
collections.abc:抽象基類,詳見抽象基類筆記
collections.deque(maxlen=n):只保留有限的n個數據
collections.defaultdict:一鍵多值字典
d = defaultdict(list) d['a'].append(1)
collections.OrderedDict:有序字典,類似pd.Series
collections.Counter:統計序列元素出現次數,並且Counter類對運算符進行了重載,支持統計結果加減,pandas
s1 = list('imabigbiggirl') s2 = list('inabigbigworld') c1 = Counter(s1) c2 = Counter(s2) print(c1) # Counter({'i': 4, 'g': 3, 'b': 2, 'm': 1, 'a': 1, 'r': 1, 'l': 1}) print(c1.most_common(3)) # [('i', 4), ('g', 3), ('b', 2)] print(c1 + c2) # Counter({'i': 7, 'g': 5, 'b': 4, 'a': 2, 'r': 2, 'l': 2, 'm': 1, 'n': 1, 'w': 1, 'o': 1, 'd': 1}) pd.Series(s1).value_counts()[:3] # pandas.Series也可以完成統計前3的功能,但是2個Seires沒法完成相加統計,NaN的加上int還是NaN
collections.namedtuple():具名元組
Stock = namedtuple('Stock', 'name shares price') s = Stock('IBM', 1000, 70) print(s) # Stock(name='IBM', shares=1000, price=70)
collections.chinamap(m1, m2, ... mn):將多個映射合並為一個,有重復key時只取第一個,有修改映射時只作用第一個
11,heapq
heapq.nlargest(it, n):在it中找出最大的n個數
heapq.nsmallest(it, n):在it中找出最小的n個數
heapq.merge(it1, it2, ..., itn):對不同類型的容器進行排序后依次迭代,注意與itertools.chain()的區別
>>> list(heapq.merge([1, 3, 5], (2, 4, 6))) [1, 2, 3, 4, 5, 6]
12,operator
itemgetter:獲取字典的value,對字典列表排序,也可以用lambada,或者將字典列表交個dataframe排序,但itemgetter效果高
ds = [{'a': 6, 'b': 2}, {'a': 3, 'b': 5}, {'a': 2, 'b': 7}, {'a': 4, 'b': 3}] # itemgetter用法示例:itemgetter返回的是一個函數,需要作用到參數上 key = itemgetter('a') for each_dict in ds: print(key(each_dict), end=' ') # 6 3 2 4 # 方法一:itemgetter ds.sort(key=itemgetter('a')) # 根據a的value排序 ds.sort(key=itemgetter('b')) # 根據b的value排序 # 方法二:lambda ds.sort(key=lambda k: k['a']) # 方法三:pandas df = pd.DataFrame(ds) # 方法三:pandas,dataframe可以接收字典列表 df = df.sort_values('a') # 根據'a'列排序,sort_values不會就地修改
attrgetter:獲取對象的屬性
class User: def __init__(self, user_id): self.user_id = user_id def __repr__(self): return 'User({})'.format(self.user_id) users = [User(3), User(10), User(7)] # attrgetter用法示例:attrgetter返回的是一個函數,需要作用到類的實例上 key = attrgetter('user_id') for u in users: print(key(u), end=' ') # 3 10 7 # 方法一:attrgetter users.sort(key=attrgetter('user_id')) # 方法二:lambda users.sort(key=lambda u: u.user_id)
methodcaller:實現getattr的功能
operator.methodcaller('distance', 0, 0)(p) # 相當於p.distance(0, 0)
13,fnmatch
fnmatch.fnmatch(filename, pattern):測試文件名是否符合pattern
>>>fnmatch.fnmatch('test.py', '*.py') True
fnmatch.fnmatchcase(filename, pattern):測試文件名是否符合pattern,嚴格區分大小寫
fnmatch.filter(filenames, pattern):對文件名列表應用pattern過濾,返回的是列表,可以用下面語句替代:
[file for file in filenames if re.match(pattern, file)]
fnmatch.translate(pattern):fnmatch將這種全局模式轉換成一個正則式?
14,glob
glob('dir/pattern') :獲取文件
glob.glob('*.py') # 獲取當前目錄下的.py文件 glob.glob('fw*.py') # 獲取當前目錄下含有fw的.py文件 glob.glob('somedir/*.py') # 獲取somedir目錄下的.py文件
15,functools
functools.partial(fun, args): 凍結參數(好像只能凍結最后一個)
def run(a, b): print(a, b) p = functools.partial(run, b='b')
functools.partial + iter:實現對固定大小內容進行迭代,f.read()可以通過partial綁定一個固定大小的參數
with open('file.data', 'rb') as f: records = iter(partial(f.read, 32), b'') # 固定大小間隔為32,哨符值為‘’ for i in records: ......
16,io
io.StringIO():類似文本文件的對象,主要有read/write/getvalue方法
io.BytesIO():類似二進制文件的對象,主要有read/write/getvalue方法
17,mmap
看起來就像bytearray,對文件進行內存映射不會將整個文件讀到內存中,而是保留一段虛擬內存,按需映射到內存中
def memory_map(filename, access=mmap.ACCESS_WRITE): size = os.path.getsize(filename) fd = os.open(filename, os.O_RDWR) return mmap.mmap(fd, size, access=access) with open('data', 'wb') as f: f.seek(999999) f.write(b'\x00') m = memory_map('data') print(len(m)) # 1000000 print(m[0: 11]) # b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' m[0: 11] = b'hello world' print(m[0: 11]) # b'hello world'
18,getpass
- getpass.getuser() # 獲取當前shell環境的用戶名
- getpass.getpass() # 輸入密碼時不顯示
19,subprocess
- subprocess.check_out() # 執行外部命令並獲取輸出
- subprocess.Popen() # 需要與子進程交互時
20,logging
- logging.getLogger() # 日志對象
- logging.bascConfig() # 設置配置信息,只能被調用一次,想修改需要通過日志對象
- logging.config.fileConfig() # 從配置文件中進行配置