一、sys模塊html
二、os模塊node
三、subprocess模塊python
四、hashlib模塊linux
五、random模塊git
六、re模塊web
七、序列化之json模塊 、 pickle模塊 和 shelve模塊算法
八、configparser模塊shell
九、xml模塊數據庫
十、requests模塊json
內置模塊
import sys
sys.argv # 實現從程序外部向程序傳遞參數。 sys.exit([arg]) # 程序中間的退出,arg=0爲正常退出。 sys.getdefaultencoding() # 獲取系統當前編碼,通常默認爲ascii。 sys.setdefaultencoding() # 設置系統默認編碼,執行dir(sys)時不會看到這個方法,在解釋器中執行不經過,能夠先執行reload(sys),在執行 setdefaultencoding('utf8'),此時將系統默認編碼設置爲utf8。(見設置系統默認編碼 ) sys.getfilesystemencoding() # 獲取文件系統使用編碼方式,Windows下返回'mbcs',mac下返回'utf-8'. sys.path # 獲取指定模塊搜索路徑的字符串集合,能夠將寫好的模塊放在獲得的某個路徑下,就能夠在程序中import時正確找到。 sys.stdin,sys.stdout,sys.stderr # stdin , stdout , 以及stderr 變量包含與標準I/O 流對應的流對象. 若是須要更好地控制輸出,而print 不能知足你的要求, 它們就是你所須要的. 你也能夠替換它們, 這時候你就能夠重定向輸出和輸入到其它設備( device ), 或者以非標準的方式處理它們 sys.maxsize # 獲取系統最大size sys.platform # 獲取當前系統平臺。 sys.version # 獲取python版本 sys.builtin_module_names # 返回一個列表,包含內建模塊的名字 sys.modules # 返回一個字典,包含模塊名字
待補充
官網
sys:https://docs.python.org/2/library/sys.html
內置模塊
import os
os.getcwd() #獲取當前工做目錄,即當前python腳本工做的目錄路徑 os.chdir("dirname") #改變當前腳本工做目錄;至關於shell下cd os.curdir #返回當前目錄: ('.') os.pardir #獲取當前目錄的父目錄字符串名:('..') os.makedirs('dirname1/dirname2') #可生成多層遞歸目錄 os.removedirs('dirname1') # 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推 os.mkdir('dirname') # 生成單級目錄;至關於shell中mkdir dirname os.rmdir('dirname') #刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname os.listdir('dirname') #列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印 os.remove() # 刪除一個文件 os.rename("oldname","newname") # 重命名文件/目錄 os.stat('path/filename') # 獲取文件/目錄信息 os.sep #輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/" os.linesep #輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n" os.pathsep #輸出用於分割文件路徑的字符串 os.name #輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix' os.system("bash command") #運行shell命令,直接顯示 os.environ #獲取系統環境變量 os.path.abspath(path) #返回path規範化的絕對路徑 os.path.split(path) #將path分割成目錄和文件名二元組返回 os.path.splitext() # 分離文件名和擴展名 os.path.dirname(path) # 返回path的目錄。其實就是os.path.split(path)的第一個元素 os.path.basename(path) # 返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素 os.path.exists(path) #若是path存在,返回True;若是path不存在,返回False os.path.isabs(path) #若是path是絕對路徑,返回True os.path.isfile(path) #若是path是一個存在的文件,返回True。不然返回False os.path.isdir(path) #若是path是一個存在的目錄,則返回True。不然返回False os.path.join(path1[, path2[, ...]]) # 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 os.path.getatime(path) #返回path所指向的文件或者目錄的最後存取時間 os.path.getmtime(path) #返回path所指向的文件或者目錄的最後修改時間 os.exit() # 退出當前進程 os.path.getsize(filename) # 返回文件或文件夾大小,與os.stat(filename).st_size
>>> os.getcwd() # 查看當前目錄 'C:\\Python36' >>> os.chdir("Lib") # 換路徑 >>> os.getcwd() # 換路徑成功 'C:\\Python36\\Lib' >>> os.curdir '.' >>> os.pardir '..' >>> os.chdir('..') # 返回 >>> os.getcwd() 'C:\\Python36' >>> os.makedirs("test1/test2") # 建立文件夾,可建立多層遞歸目錄 >>> os.chdir("test1/test2") >>> os.getcwd() # 建立成功 'C:\\Python36\\test1\\test2' >>> os.chdir('..') # 返回 >>> os.getcwd() 'C:\\Python36\\test1' >>> os.removedirs('test2') # 刪除文件夾 >>> os.chdir('test2') # 已成功刪除 Traceback (most recent call last): File "<pyshell#16>", line 1, in <module> os.chdir('test2') FileNotFoundError: [WinError 2] 系統找不到指定的文件。: 'test2' >>>os.mkdir('dirname') # 建立文件夾 >>> os.chdir('dirname') >>> os.getcwd() # 建立成功 'C:\\Python36\\test1\\dirname' >>> os.chdir('..') >>> os.getcwd() 'C:\\Python36\\test1' >>> os.rmdir('dirname') # 刪除文件夾 >>> os.chdir('dirname') Traceback (most recent call last): File "<pyshell#23>", line 1, in <module> os.chdir('dirname') FileNotFoundError: [WinError 2] 系統找不到指定的文件。: 'dirname' >>> os.listdir() [] >>> os.chdir('..') >>> os.listdir() # 列出本文件夾的文件夾或文件 ['a.txt', 'DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python3.dll', 'python3.exe', 'python36.dll', 'pythonw.exe', 'qt.conf', 'README.txt', 'Scripts', 'selenium', 'tcl', 'test.bak', 'test.dat', 'test.dir', 'test1', 'Tools', 'vcruntime140.dll'] >>> os.chdir('test1') >>> os.listdir() ['test.txt', 'test1.txt'] >>> os.remove('test.txt') # 刪除單個文件,注意是文件。 >>> os.listdir() # 刪除成功 ['test1.txt'] >>> os.rename('test1.txt','test1_rename.txt') # 修改文件夾或文件的名字 >>> os.listdir() ['test1_rename.txt'] >>> os.stat('test1_rename.txt') # 查看文件夾或文件的信息 os.stat_result(st_mode=33206, st_ino=6755399441094891, st_dev=1315649016, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1500994476, st_mtime=1500994476, st_ctime=1500994476) >>> os.sep # 系統分隔符,windows是\\,linux是/ '\\' >>> os.linesep #輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n" '\r\n' >>> os.pathsep #輸出用於分割文件路徑的字符串 ';' >>> os.name #輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix' 'nt' >>> os.system("bash command") #運行shell命令,直接顯示 1 >>> os.environ #獲取系統環境變量 environ({'ALLUSERSPROFILE': 'C:\\ProgramData', 'APPDATA': 'C:\\Users\\fat39\\AppData\\Roaming', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'COMPUTERNAME': 'FAT39-PC', 。。。略}) >>> os.path.abspath('test') #返回path規範化的絕對路徑 'C:\\Python36\\test1\\test' >>> os.path.split('test') #將path分割成目錄和文件名二元組返回 ('', 'test') >>> os.path.splitext('test1_rename.txt') # 分離文件名和擴展名 ('test1_rename', '.txt') >>> os.path.dirname('test\\test\\test\\test1_rename.txt') # 返回path的目錄。其實就是os.path.split(path)的第一個元素 'test\\test\\test' >>> os.path.dirname(r'test\test\test\test1_rename.txt') # 返回path的目錄。其實就是os.path.split(path)的第一個元素 'test\\test\\test' >>> os.path.basename(r'test\test\test\test1_rename.txt') # 返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素 'test1_rename.txt' >>> os.path.exists(r'test\test\test\test1_rename.txt') #若是path存在,返回True;若是path不存在,返回False False >>> os.path.exists(r'test1_rename.txt') #若是path存在,返回True;若是path不存在,返回False True >>> os.path.isabs(r'test1_rename.txt') #若是path是絕對路徑,返回True False >>> os.path.isfile(r'test\test\test\test1_rename.txt') #若是path是一個存在的文件,返回True。不然返回False False >>> os.path.isfile(r'test1_rename.txt') #若是path是一個存在的文件,返回True。不然返回False True >>> os.path.isdir('test2') #若是path是一個存在的目錄,則返回True。不然返回False True >>> os.path.isdir('test1_rename.txt') #若是path是一個存在的目錄,則返回True。不然返回False False >>> os.path.join('test1','test2') # 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 'test1\\test2' >>> os.path.getatime('test1_rename.txt') #返回path所指向的文件或者目錄的最後存取時間 1500994476.0000696 >>> os.path.getmtime('test1_rename.txt') #返回path所指向的文件或者目錄的最後存取時間 1500994476.0000696 >>> os.path.getsize('test1_rename.txt') # 返回文件或文件夾大小,與os.stat(filename).st_size 0 >>> os.path.getsize('test2') # 返回文件或文件夾大小,與os.stat(filename).st_size 0
官網:
os:https://docs.python.org/2/library/os.html
內置模塊
ipmort subprocess
能夠執行shell命令的相關模塊和函數有:
os.system os.spawn* os.popen* --廢棄 popen2.* --廢棄 commands.* --廢棄,3.x中被移除
以上執行shell命令的相關的模塊和函數的功能均在 subprocess 模塊中實現,並提供了更豐富的功能。
subprocess的目的就是啓動一個新的進程而且與之通訊。
1 call # 執行命令,返回狀態碼執行命令,並返回執行狀態,其中shell參數爲False時,命令須要經過列表的方式傳入,當shell爲True時,可直接傳入命令。若是出現錯誤,不進行報錯。 2 check_call # 用法與subprocess.call()相似,區別是,當返回值不爲0時,直接拋出異常。 3 check_output # 用法與上面兩個方法相似,區別是,若是當返回值爲0時,直接返回輸出結果,若是返回值不爲0,直接拋出異常。須要說明的是,該方法在python3.x中才有。 4 subprocess.Popen() # 用於執行復雜的系統命令 5 # subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
1 args:shell命令,能夠是字符串或者序列類型(如:list,元組) 2 bufsize:指定緩衝。0 無緩衝,1 行緩衝,其餘 緩衝區大小,負值 系統緩衝 3 stdin, stdout, stderr:分別表示程序的標準輸入、輸出、錯誤句柄 4 preexec_fn:只在Unix平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行以前被調用 5 close_sfs:在windows平臺下,若是close_fds被設置爲True,則新建立的子進程將不會繼承父進程的輸入、輸出、錯誤管道。 6 因此不能將close_fds設置爲True同時重定向子進程的標準輸入、輸出與錯誤(stdin, stdout, stderr)。 7 shell:同上 8 cwd:用於設置子進程的當前目錄 9 env:用於指定子進程的環境變量。若是env = None,子進程的環境變量將從父進程中繼承。 10 universal_newlines:不一樣系統的換行符不一樣,True -> 贊成使用 \n 11 startupinfo與createionflags只在windows下有效 12 將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等
child.wait() # 等待子進程,相似於併發的join child.poll() # 檢查子進程狀態 child.kill() # 終止子進程 child.send_signal() # 向子進程發送信號 child.terminate() # 終止子進程 ps: 子進程的PID存儲在child.pid
(3)驗證
call() 和 check_call()使用方法以下:
import subprocess subprocess.call("ls -l", shell=True) # subprocess.call(["ls", "-l"], shell=False) ''' 總用量 4 -rw-r--r--. 1 root root 98 4月 7 13:53 mp.py drwxr-xr-x. 2 root root 6 4月 7 14:15 t1 0 ''' subprocess.call("ping www.baidu.com",shell=True) ''' PING www.a.shifen.com (163.177.151.110) 56(84) bytes of data. 64 bytes from 163.177.151.110: icmp_seq=1 ttl=128 time=68.9 ms 64 bytes from 163.177.151.110: icmp_seq=2 ttl=128 time=36.5 ms --- www.a.shifen.com ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 36.599/52.767/68.936/16.170 ms 0 ''' subprocess.call("ssh 1.1.1.40",shell=True) # 經過call方法,直接從python跳轉到ssh,python運行卡在這裏 ''' root@1.1.1.40's password: Last login: Sat Apr 7 10:07:14 2018 from 1.1.1.39 [root@fat40 ~]# ''' # 以上,若執行成功,return值均爲0
>>> res = subprocess.check_output('ls -l',shell=True) >>> res # 輸出結果爲bytes格式 b'\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 4\n-rw-r--r--. 1 root root 98 4\xe6\x9c\x88 7 13:53 mp.py\ndrwxr-xr-x. 2 root root 6 4\xe6\x9c\x88 7 14:15 t1\n' >>> res = subprocess.check_output("asdfsadfsadf",shell=True) /bin/sh: asdfsadfsadf: 未找到命令 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python3.6/subprocess.py", line 336, in check_output **kwargs).stdout File "/usr/local/lib/python3.6/subprocess.py", line 418, in run output=stdout, stderr=stderr) subprocess.CalledProcessError: Command 'asdfsadfsadf' returned non-zero exit status 127. >>>
################## mp.py #################### import subprocess child = subprocess.Popen(['ping','-c','4','www.baidu.com']) print('hello') [root@fat39 test]# python3 mp.py ''' hello [root@fat39 test]# PING www.a.shifen.com (163.177.151.110) 56(84) bytes of data. 64 bytes from 163.177.151.110: icmp_seq=1 ttl=128 time=12.9 ms 64 bytes from 163.177.151.110: icmp_seq=2 ttl=128 time=37.4 ms 64 bytes from 163.177.151.110: icmp_seq=3 ttl=128 time=132 ms 64 bytes from 163.177.151.110: icmp_seq=4 ttl=128 time=687 ms --- www.a.shifen.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3005ms rtt min/avg/max/mdev = 12.932/217.491/687.172/274.817 ms ''' ################## mp2.py #################### import subprocess child = subprocess.Popen(['ping','-c','4','www.baidu.com']) child.wait() print('hello') [root@fat39 test]# python3 mp2.py ''' PING www.a.shifen.com (163.177.151.110) 56(84) bytes of data. 64 bytes from 163.177.151.110: icmp_seq=1 ttl=128 time=443 ms 64 bytes from 163.177.151.110: icmp_seq=2 ttl=128 time=539 ms 64 bytes from 163.177.151.110: icmp_seq=3 ttl=128 time=109 ms 64 bytes from 163.177.151.110: icmp_seq=4 ttl=128 time=36.1 ms --- www.a.shifen.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3004ms rtt min/avg/max/mdev = 36.177/282.106/539.028/213.638 ms hello '''
import subprocess child = subprocess.Popen('ls -l',shell=True,stdout=subprocess.PIPE) print(child.stdout.read()) """ b'\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 8\n-rw-r--r--. 1 root root 111 4\xe6\x9c\x88 7 14:51 mp2.py\n-rw-r--r--. 1 root root 98 4\xe6\x9c\x88 7 13:53 mp.py\ndrwxr-xr-x. 2 root root 6 4\xe6\x9c\x88 7 14:15 t1\n' """ """ print(child.communicate()) (b'\xe6\x80\xbb\xe7\x94\xa8\xe9\x87\x8f 8\n-rw-r--r--. 1 root root 111 4\xe6\x9c\x88 7 14:51 mp2.py\n-rw-r--r--. 1 root root 98 4\xe6\x9c\x88 7 13:53 mp.py\ndrwxr-xr-x. 2 root root 6 4\xe6\x9c\x88 7 14:15 t1\n', None) """ import subprocess child1 = subprocess.Popen(['cat','/etc/passwd'],stdout=subprocess.PIPE) child2 = subprocess.Popen(['grep','root'],stdin=child1.stdout,stdout=subprocess.PIPE) print(child2.communicate()) # subprocess.PIPE實際上爲文本流提供一個緩存區。child1的stdout將文本輸出到緩存區,隨後child2的stdin從該PIPE中將文本讀取走。child2的輸出文本也被存放在PIPE中,直到communicate()方法從PIPE中讀取出PIPE中的文本。注意:communicate()是Popen對象的一個方法,該方法會阻塞父進程,直到子進程完成 ''' (b'root:x:0:0:root:/root:/bin/bash\noperator:x:11:0:operator:/root:/sbin/nologin\n', None) ''' import subprocess obj = subprocess.Popen("python",shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") obj.stdin.close() cmd_out = obj.stdout.read() """ 1 2 """ obj.stdout.close() cmd_error = obj.stderr.read() # 空白 obj.stderr.close() import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") out_error_list = obj.communicate() print(out_error_list) # ('1\n2\n', '') import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out_error_list = obj.communicate('print("hello")') print(out_error_list) # ('hello\n', '')
(4)參考
參考:
http://www.cnblogs.com/wupeiqi/articles/5501365.html
http://www.javashuo.com/article/p-tmvlkdgo-c.html
內置模塊
import hashlib
Python的hashlib提供了常見的摘要算法,如MD5,SHA1等等。
什麼是摘要算法呢?摘要算法又稱哈希算法、散列算法。它經過一個函數,把任意長度的數據轉換爲一個長度固定的數據串(一般用16進制的字符串表示)。
摘要算法就是經過摘要函數f()對任意長度的數據data計算出固定長度的摘要digest,目的是爲了發現原始數據是否被人篡改過。
摘要算法之因此能指出數據是否被篡改過,就是由於摘要函數是一個單向函數,計算f(data)很容易,但經過digest反推data卻很是困難。並且,對原始數據作一個bit的修改,都會致使計算出的摘要徹底不一樣。
from hashlib import md5, sha1, sha224, sha256, sha384, sha512 from pprint import pprint hash_funcs = [md5, sha1, sha224, sha256, sha384, sha512] def hash_show(s): result = [] for func in hash_funcs: # 逐個算法 s_hash_obj = func(s) s_hash_hex = s_hash_obj.hexdigest() result.append((s_hash_obj.name, s_hash_hex, len(s_hash_hex))) return result if __name__ == '__main__': s = 'hello python'.encode("utf-8") rs = hash_show(s) pprint(rs)
#hashlib簡單使用 def md5(arg):#這是加密函數,將傳進來的函數加密 md5_pwd = hashlib.md5(bytes('abd',encoding='utf-8')) md5_pwd.update(bytes(arg,encoding='utf-8')) return md5_pwd.hexdigest()#返回加密的數據 def log(user,pwd):#登錄時候時候的函數,因爲md5不能反解,所以登錄的時候用正解 with open('db','r',encoding='utf-8') as f: for line in f: u,p=line.strip().split('|') if u ==user and p == md5(pwd):#登錄的時候驗證用戶名以及加密的密碼跟以前保存的是否同樣 return True def register(user,pwd):#註冊的時候把用戶名和加密的密碼寫進文件,保存起來 with open('db','a',encoding='utf-8') as f: temp = user+'|'+md5(pwd) f.write(temp) i=input('1表示登錄,2表示註冊:') if i=='2': user = input('用戶名:') pwd =input('密碼:') register(user,pwd) elif i=='1': user = user = input('用戶名:') pwd =input('密碼:') r=log(user,pwd)#驗證用戶名和密碼 if r ==True: print('登錄成功') else: print('登錄失敗') else: print('帳號不存在')
from random import Random from hashlib import md5 # 獲取由4位隨機大小寫字母、數字組成的salt值 def create_salt(length=4): salt = '' chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789' len_chars = len(chars) - 1 random = Random() for i in range(length): # 每次從chars中隨機取一位 salt += chars[random.randint(0, len_chars)] return salt # 獲取原始密碼+salt的md5值 def create_md5(pwd, salt): md5_obj = md5() md5_obj.update(pwd + salt) return md5_obj.hexdigest() # 原始密碼 pwd = '20141124' # 隨機生成4位salt salt = create_salt() # 加密後的密碼 md5 = create_md5(bytes(pwd,encoding="utf-8"), bytes(salt,encoding="utf-8")) print(pwd) # 20141124 print(salt) # wAAn # 隨機 print(md5) # 7b22cb2fed415097c942b130f210aac3 ''' 數據庫: username | md5 | salt 20141124 | xxx | xxx '''
(4)參考
https://blog.csdn.net/secret5/article/details/70150486
http://www.javashuo.com/article/p-ksyusxok-o.html
內置模塊
import random
random.seed(a=None, version=2) # 初始化僞隨機數生成器。若是未提供a或者a=None,則使用系統時間爲種子。若是a是一個整數,則做爲種子。 random.getstate() # 返回一個當前生成器的內部狀態的對象 random.setstate(state) # 傳入一個先前利用getstate方法得到的狀態對象,使得生成器恢復到這個狀態。 random.getrandbits(k) # 返回range(0,2**k)之間的一個整數,至關於randrange(0,2**k) random.randrange(stop) # 返回range(0,stop)之間的一個整數 random.randrange(start, stop[, step]) # 返回range(start,stop)之間的一個整數,可加step,跟range(0,10,2)相似 random.randint(a, b) # 返回range(a,b+1)之間的一個整數,等價於然的range(a,b+1) random.choice(seq) # 從非空序列seq中隨機選取一個元素。若是seq爲空則彈出 IndexError異常。 random.choices(population, weights=None, *, cum_weights=None, k=1) # 3.6版本新增。從population集羣中隨機抽取K個元素(可重複)。weights是相對權重列表,cum_weights是累計權重,兩個參數不能同時存在。 random.shuffle(x[, random]) # 隨機打亂序列x內元素的排列順序。只能針對可變的序列,對於不可變序列,請使用下面的sample()方法。 random.sample(population, k) # 從population樣本或集合中隨機抽取K個不重複的元素造成新的序列。經常使用於不重複的隨機抽樣。返回的是一個新的序列,不會破壞原有序列。要從一個整數區間隨機抽取必定數量的整數,請使用sample(range(10000000), k=60)相似的方法,這很是有效和節省空間。若是k大於population的長度,則彈出ValueError異常。 random.random() # 返回一個介於左閉右開[0.0, 1.0)區間的浮點數 random.uniform(a, b) # 返回一個介於a和b之間的浮點數。若是a>b,則是b到a之間的浮點數。這裏的a和b都有可能出如今結果中。 random.triangular(low, high, mode) # 返回一個low <= N <=high的三角形分佈的隨機數。參數mode指明衆數出現位置。 random.betavariate(alpha, beta) # β分佈。返回的結果在0~1之間 random.expovariate(lambd) # 指數分佈 random.gammavariate(alpha, beta) # 伽瑪分佈 random.gauss(mu, sigma) # 高斯分佈 random.lognormvariate(mu, sigma) # 對數正態分佈 random.normalvariate(mu, sigma) # 正態分佈 random.vonmisesvariate(mu, kappa) # 卡帕分佈 random.paretovariate(alpha) # 帕累託分佈 random.weibullvariate(alpha, beta) # 威布爾分佈
>>> random() # 隨機浮點數: 0.0 <= x < 1.0 0.37444887175646646 >>> uniform(2.5, 10.0) # 隨機浮點數: 2.5 <= x < 10.0 3.1800146073117523 >>> randrange(10) # 0-9的整數: >>> randrange(0, 101, 2) # 0-100的偶數 >>> choice(['win', 'lose', 'draw']) # 從序列隨機選擇一個元素 'draw' >>> deck = 'ace two three four'.split() >>> shuffle(deck) # 對序列進行洗牌,改變原序列 >>> deck ['four', 'two', 'ace', 'three'] >>> sample([10, 20, 30, 40, 50], k=4) # 不改變原序列的抽取指定數目樣本,並生成新序列 [40, 10, 50, 30] >>> # 6次旋轉紅黑綠輪盤(帶權重可重複的取樣),不破壞原序列,weight[18,18,2] >>> choices(['red', 'black', 'green'], [18, 18, 2], k=6) ['red', 'green', 'black', 'black', 'red', 'black'] >>> # 德州撲克計算機率Deal 20 cards without replacement from a deck of 52 playing cards >>> # and determine the proportion of cards with a ten-value >>> # (a ten, jack, queen, or king). >>> deck = collections.Counter(tens=16, low_cards=36) >>> seen = sample(list(deck.elements()), k=20) >>> seen.count('tens') / 20 0.15 >>> # 模擬機率Estimate the probability of getting 5 or more heads from 7 spins >>> # of a biased coin that settles on heads 60% of the time.'H'的機率是0.6,「T」的機率是1-0.6 >>> trial = lambda: choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5 >>> sum(trial() for i in range(10000)) / 10000 0.4169 >>> # Probability of the median of 5 samples being in middle two quartiles >>> trial = lambda : 2500 <= sorted(choices(range(10000), k=5))[2] < 7500 >>> sum(trial() for i in range(10000)) / 10000 0.7958 >>> from statistics import mean >>> from random import choices >>> data = 1, 2, 4, 4, 10 >>> means = sorted(mean(choices(data, k=5)) for i in range(20)) # mean是求平均 >>> print(f'The sample mean of {mean(data):.1f} has a 90% confidence ' f'interval from {means[1]:.1f} to {means[-2]:.1f}') # 這裏的f用法
import random checkcode = '' for i in range(4): current = random.randrange(0,4) if current != i: temp = chr(random.randint(65,90)) else: temp = random.randint(0,9) checkcode += str(temp) print(checkcode)
import random, string def gen_random_string(length): # 數字的個數隨機產生 num_of_numeric = random.randint(1,length-1) # 剩下的都是字母 num_of_letter = length - num_of_numeric # 隨機生成數字 numerics = [random.choice(string.digits) for i in range(num_of_numeric)] # 隨機生成字母 letters = [random.choice(string.ascii_letters) for i in range(num_of_letter)] # 結合二者 all_chars = numerics + letters # 洗牌 random.shuffle(all_chars) # 生成最終字符串 result = ''.join([i for i in all_chars]) return result if __name__ == '__main__': print(gen_random_string(64))
http://www.javashuo.com/article/p-mtdojeem-br.html
什麼是序列化
咱們把對象(變量)從內存中變成可存儲或傳輸的過程稱之爲序列化,在Python中叫pickling,在其餘語言中也被稱之爲serialization,marshalling,flattening等等,都是一個意思。序列化以後,就能夠把序列化後的內容寫入磁盤,或者經過網絡傳輸到別的機器上。反過來,把變量內容從序列化的對象從新讀到內存裏稱之爲反序列化,即unpickling。
python用於序列化的兩個模塊
另,可以使用內置方法eval(xxxxx),但效果有限。
內置模塊
import json
json,Json模塊提供了四個功能:dumps、dump、loads、load
dumps # 將字典轉換成字符串,轉換後的字典中的元素是由雙引號表示的 dump # dump方法接收一個文件句柄,直接將字典轉換成json字符串寫入文件 loads # 將一個字符串轉換成字典類型 load # load方法接收一個文件句柄,直接將文件中的json字符串轉換成數據結構返回
import json dic={'k1':'v1','k2':'v2','k3':'v3'} # dict類型 # 寫dumps with open("test.json","w") as f: str_dic = json.dumps(dic) # str類型 f.write(str_dic) # f內容以下:{"k1": "v1", "k2": "v2", "k3": "v3"} # 讀loads with open("test.json","r") as f: str_dic = f.read() # str類型,內容是: {"k1": "v1", "k2": "v2", "k3": "v3"} dic = json.loads(str_dic) # dict類型,內容是:{"k1": "v1", "k2": "v2", "k3": "v3"} # 寫dump dic2={'k4':'v4','k5':'v5','k6':'v6'} # dict類型 with open("test2.json","w") as f: json.dump(dic2,f) # f內容以下:{"k4": "v4", "k5": "v5", "k6": "v6"} # 讀loads with open("test2.json","r") as f: res = json.load(f) # dict類型,內容是{'k4': 'v4', 'k5': 'v5', 'k6': 'v6'}
################ JSONEncoder ############# import json from datetime import datetime,date class JsonCustomEncoder(json.JSONEncoder): def default(self, value): if isinstance(value, datetime): return value.strftime('%Y-%m-%d %H:%M:%S') # 轉換爲字符串 elif isinstance(value, date): return value.strftime('%Y-%m-%d') # 轉換爲字符串 else: return json.JSONEncoder.default(self, value) dt = datetime.now() d = date.today() print(json.dumps(dt,cls=JsonCustomEncoder)) # "2018-04-06 09:52:03" print(json.dumps(d,cls=JsonCustomEncoder)) # "2018-04-06" ################ JSONDecoder ############# 簡單驗證,待完善 import json dt = "2018-04-06 09:51:30" d = "2018-04-06" class JsonCustomDecoder(json.JSONDecoder): def decode(self,value): import time return time.strptime(value, "%Y-%m-%d %X") print(json.loads(dt,cls=JsonCustomDecoder)) # time.struct_time(tm_year=2018, tm_mon=4, tm_mday=6, tm_hour=9, tm_min=51, tm_sec=30, tm_wday=4, tm_yday=96, tm_isdst=-1)
import json v = {"k":"中國人"} ret = json.dumps(v) # 默認ensure_ascii=True,把中文也轉爲unicode print(ret) # {"k": "\u4e2d\u56fd\u4eba"} ret = json.dumps(v,ensure_ascii=False) # 不把中文轉爲unicode print(ret) # {"k": "中國人"}
(4)參考
內置模塊
import pickle
pickle支持全部python數據類型,pickle模塊提供了四個功能:dumps、dump、loads、load,與json類型
import pickle dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic=pickle.dumps(dic) # # bytes類型,內容是: b'\x80\x03}q\x00(X\x02\x00\x00\x00k1q\x01X\x02\x00\x00\x00v1q\x02X\x02\x00\x00\x00k2q\x03X\x02\x00\x00\x00v2q\x04X\x02\x00\x00\x00k3q\x05X\x02\x00\x00\x00v3q\x06u.' dic2 = pickle.loads(str_dic) # dict類型,內容是: {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} with open("test2.pickle","wb") as f: # b模式 pickle.dump(dic,f) with open("test2.pickle","rb") as f: # b模式 x=pickle.load(f) # dict類型,內容是:{'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} import time now = time.localtime() # struct time with open("test3.pickle","wb") as f: pickle.dump(now,f) with open("test3.pickle","rb") as f: x = pickle.load(f) # time類型,內容是: time.struct_time(tm_year=2018, tm_mon=4, tm_mday=6, tm_hour=10, tm_min=3, tm_sec=41, tm_wday=4, tm_yday=96, tm_isdst=0)
內容模塊
import shelve
shelve也是python提供給咱們的序列化工具,比pickle用起來更簡單一些。
shelve只提供給咱們一個open方法,是用key來訪問的,使用起來和字典相似。
這個模塊有個限制,它不支持多個應用同一時間往同一個DB進行寫操做。因此當咱們知道咱們的應用若是隻進行讀操做,咱們可讓shelve經過只讀方式打開DB
import shelve f = shelve.open(r'shelve.txt') ########## 寫 ############ f['stu1_info']={'name':'alex','age':'18'} f['stu2_info']={'name':'alvin','age':'20'} f['school_info']={'website':'oldboyedu.com','city':'beijing'} f.close() ########## 讀 ############ f = shelve.open(r'shelve.txt') print(f.get("stu1_info")["age"]) # 18
內置模塊
import configparser
源文件指定格式
# 註釋1 ; 註釋2 [section1] # 節點 k1 = v1 # 值 k2:v2 # 值 [section2] # 節點 k1 = v1 # 值
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') ret = config.sections() print(ret)
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') ret = config.items('section1') print(ret)
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') ret = config.options('section1') print(ret)
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') v = config.get('section1', 'k1') # v = config.getint('section1', 'k1') # v = config.getfloat('section1', 'k1') # v = config.getboolean('section1', 'k1') print(v)
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') # 檢查 has_sec = config.has_section('section1') print(has_sec) # 添加節點 config.add_section("SEC_1") config.write(open('xxxooo', 'w')) # 刪除節點 config.remove_section("SEC_1") config.write(open('xxxooo', 'w'))
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') # 檢查 has_opt = config.has_option('section1', 'k1') print(has_opt) # 刪除 config.remove_option('section1', 'k1') config.write(open('xxxooo', 'w')) # 設置 config.set('section1', 'k10', "123") config.write(open('xxxooo', 'w'))
(3)驗證
#-*- encoding: utf-8 -*- import configparser # 一、conf = configparser.ConfigParser() # 二、settings = configparser.ConfigParser(interpolation=ExtendedInterpolation()) # 讀ini文件,初始化不同,用法同樣 test = \ ''' [db] db_host = 127.0.0.1 db_port = 3306 db_user = root db_pass = 123 [concurrent] thread = 10 processor = 20 ''' test_dict = { "db":{ "db_host":"127.0.0.1", "db_port":"3306", "db_user":"root", "db_pass":"123" }, "concurrent":{ "thread":"10", "processor":"20" }, "lab":{ "name":"tom", "password":"123" } } conf = configparser.ConfigParser() conf.read("test.conf") # 讀取文件 # conf.read_string(test) # 讀取str,好比上面的test字段 # conf.read_dict(test_dict) # 讀取dict,好比上面的test_dict db_option = conf.options("db") # 讀取option,至關於dict的key,['db_host', 'db_port', 'db_user', 'db_pass'] db_items = conf.items("db") # 至關於dict的item,[('db_host', '127.0.0.1'), ('db_port', '3306'), ('db_user', 'root'), ('db_pass', '123')] sec = conf.sections() # 讀取標題,['db', 'concurrent'] #--------------------------------------------------------------------------------- db_host = conf.get("db","db_host") # type str 127.0.0.1 db_port = conf.getint("db","db_port") # type int 3306 db_user = conf.get("db","db_user") # type str root db_pass = conf.get("db","db_pass") # type str 123 concurrent_thread = conf.getint("concurrent","thread") # type int 10 concurrent_processor = conf.getint("concurrent","processor") # type int 20 #--------------------------------------------------------------------------------- conf.set("db", "db_pass", "test123") # 修改section db 的db_pass,新值是test123 conf.set("db","db_test","test_db") # 新增,與修改是一個用法 #--------------------------------------------------------------------------------- conf.add_section("abc") # 增長section,abc conf.set("abc","country","CN") # 增長字段 conf.set("abc","time_zone","+8") #--------------------------------------------------------------------------------- print(conf.has_section("db")) # True print(conf.has_section("abcdefg")) # False print(conf.has_option("abc","country")) # True print(conf.has_option("abc","abc_name")) # False #--------------------------------------------------------------------------------- new_dict = { "guest":{ "name":"guest", "password":"123" } } conf.update(new_dict) # 直接經過dict更新 #--------------------------------------------------------------------------------- with open("test1.conf","w") as f: conf.write(f) """ [db] db_host = 127.0.0.1 db_port = 3306 db_user = root db_pass = test123 db_test = test_db [concurrent] thread = 10 processor = 20 [abc] country = CN time_zone = +8 [guest] name = guest password = 123 """ #--------------------------------------------------------------------------------- settings_ini = \ """ [SectionOne] Param1: Hello Param2: World [SectionTwo] Param1: ${SectionOne:Param1} ${SectionOne:Param2} [SectionThree] Alpha: One Bravo: Two Charlie: ${Alpha} Mississippi """ settings = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation()) # 用法同上 settings.read_string(settings_ini) sec = settings.sections() # ['SectionOne', 'SectionTwo', 'SectionThree'] SectionThree = settings.items("SectionThree") print(SectionThree) # [('alpha', 'One'), ('bravo', 'Two'), ('charlie', 'One Mississippi')]
http://www.javashuo.com/article/p-yoadyzgj-d.html
內置模塊
import logging
logging.basicConfig()函數中可經過具體參數來更改logging模塊默認行爲,可用參數有: filename:用指定的文件名建立FiledHandler,這樣日誌會被存儲在指定的文件中。 filemode:文件打開方式,在指定了filename時使用這個參數,默認值爲「a」還可指定爲「w」。 format:指定handler使用的日誌顯示格式。 datefmt:指定日期時間格式。 level:設置rootlogger(後邊會講解具體概念)的日誌級別 stream:用指定的stream建立StreamHandler。能夠指定輸出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默認爲sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。 format參數中可能用到的格式化串: %(name)s Logger的名字 %(levelno)s 數字形式的日誌級別 %(levelname)s 文本形式的日誌級別 %(pathname)s 調用日誌輸出函數的模塊的完整路徑名,可能沒有 %(filename)s 調用日誌輸出函數的模塊的文件名 %(module)s 調用日誌輸出函數的模塊名 %(funcName)s 調用日誌輸出函數的函數名 %(lineno)d 調用日誌輸出函數的語句所在的代碼行 %(created)f 當前時間,用UNIX標準的表示時間的浮 點數表示 %(relativeCreated)d 輸出日誌信息時的,自Logger建立以 來的毫秒數 %(asctime)s 字符串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒 %(thread)d 線程ID。可能沒有 %(threadName)s 線程名。可能沒有 %(process)d 進程ID。可能沒有 %(message)s用戶輸出的消息
CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0
另轉了一篇logging模塊文章:(轉)一篇寫的簡明易懂的logging模塊
補充:想改一下logging的方法如這裏的info,但發現logging.getLogger(log_type)返回是一個實例對象,因此嘗試了下面的方法,僅作記錄。
# -*- coding:utf-8 -*- from cl.conf import settings import logging import os def test(system_log): class Test(type(system_log)): def info(self,*args,**kwargs): res = super(Test, self).info(*args,**kwargs) print("test info") return res return Test def logger(log_type): logger = logging.getLogger(log_type) '''############# 增長了這一條 #############''' logger = test(logger)(log_type) '''############# 增長了這一條 #############''' logger.setLevel(settings.LOG_LEVEL) # create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(settings.LOG_LEVEL) # create file handler and set level to warning log_file = os.path.join(settings.LOG_FILES_DIR,settings.LOG_TYPES[log_type]) fh = logging.FileHandler(log_file) fh.setLevel(settings.LOG_LEVEL) # create formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # add formatter to ch and fh ch.setFormatter(formatter) fh.setFormatter(formatter) # add ch and fh to logger logger.addHandler(ch) # #logger對象能夠添加多個fh和ch對象 logger.addHandler(fh) return logger system_log = logger("system") # system_log.info("haha") print(test(system_log).__mro__) # (<class '__main__.test.<locals>.Test'>, <class '__main__.test.<locals>.Test'>, <class 'logging.Logger'>, <class 'logging.Filterer'>, <class 'object'>)
# -*- coding:utf-8 -*- from cl.conf import settings import logging import os from logging import Logger class NewLogger(Logger): def info(self, *args, **kwargs): res = super(NewLogger, self).info(*args, **kwargs) print("test info") return res def test(system_log): class Test(type(system_log)): def info(self,*args,**kwargs): res = super(Test, self).info(*args,**kwargs) print("test info") return res return Test def logger(log_type): # logger = logging.getLogger(log_type) logger = NewLogger(log_type) '''############# 增長了這一條 #############''' # logger = test(logger)(log_type) '''############# 增長了這一條 #############''' logger.setLevel(settings.LOG_LEVEL) # create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(settings.LOG_LEVEL) # create file handler and set level to warning log_file = os.path.join(settings.LOG_FILES_DIR,settings.LOG_TYPES[log_type]) fh = logging.FileHandler(log_file) fh.setLevel(settings.LOG_LEVEL) # create formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # add formatter to ch and fh ch.setFormatter(formatter) fh.setFormatter(formatter) # add ch and fh to logger logger.addHandler(ch) # #logger對象能夠添加多個fh和ch對象 logger.addHandler(fh) return logger system_log = logger("system") system_log.info("haha") # print(test(system_log).__mro__) # (<class '__main__.test.<locals>.Test'>, <class '__main__.test.<locals>.Test'>, <class 'logging.Logger'>, <class 'logging.Filterer'>, <class 'object'>)
(3)驗證
實驗一
import logging logging.basicConfig(filename='log.log', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', level=10) logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical') logging.log(10, 'log') ''' 2018-04-11 22:50:11 PM - root - DEBUG -test1: debug 2018-04-11 22:50:11 PM - root - INFO -test1: info 2018-04-11 22:50:11 PM - root - WARNING -test1: warning 2018-04-11 22:50:11 PM - root - ERROR -test1: error 2018-04-11 22:50:11 PM - root - CRITICAL -test1: critical 2018-04-11 22:50:11 PM - root - DEBUG -test1: log '''
實驗二 多個日誌文件
# -*- coding:utf-8 -*- import logging # 定義文件 file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8') fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s") file_1_1.setFormatter(fmt) file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8') fmt = logging.Formatter() file_1_2.setFormatter(fmt) # 定義日誌 logger1 = logging.Logger('s1', level=logging.ERROR) logger1.addHandler(file_1_1) logger1.addHandler(file_1_2) # 寫日誌 logger1.critical('1111') ############# l1.1.log ################ 2018-04-11 22:52:29,330 - s1 - CRITICAL -test2: 1111 ############# l1.2.log ################ 1111
實驗三
# -*- coding:utf-8 -*- import os import logging ############### 可寫入settings.py ############### BASE_DIR = os.path.dirname(os.path.abspath(__file__)) LOG_LEVEL = logging.INFO LOG_TYPES = { 'system': 'system.log', 'interactive':"interactive.log" } def logger(log_type): # create logger logger = logging.getLogger(log_type) logger.setLevel(LOG_LEVEL) # create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(LOG_LEVEL) # create file handler and set level to warning log_file = "%s/log/%s" % (BASE_DIR, LOG_TYPES[log_type]) fh = logging.FileHandler(log_file) fh.setLevel(LOG_LEVEL) # create formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # add formatter to ch and fh ch.setFormatter(formatter) fh.setFormatter(formatter) # add ch and fh to logger logger.addHandler(ch) # #logger對象能夠添加多個fh和ch對象 logger.addHandler(fh) return logger
# -*- coding:utf-8 -*- import logger interact_log = logger.logger("interactive") system_log = logger.logger("system") ############## 腳本開始 ############## system_log.info("程序開始") while True: cmd = input(">>:") print("執行命令,返回結果") if cmd.startswith("rm"): interact_log.warning(cmd) else: interact_log.info(cmd) if cmd == "exit": system_log.info("退出程序") exit()
########### interactive.log ########### 2018-04-11 22:36:32,417 - interactive - INFO - hi 2018-04-11 22:36:34,679 - interactive - INFO - ll 2018-04-11 22:36:38,597 - interactive - INFO - dsf 2018-04-11 22:36:41,887 - interactive - WARNING - rm -rf / 2018-04-11 22:37:07,331 - interactive - INFO - ok 2018-04-11 22:37:08,397 - interactive - INFO - exit 注:因爲配置了StreamHandler,以上均在屏幕上顯示出來 ########### system.log ########### 2018-04-11 22:36:26,650 - system - INFO - 程序開始 2018-04-11 22:37:08,398 - system - INFO - 退出程序 注:因爲配置了StreamHandler,以上均在屏幕上顯示出來
http://www.cnblogs.com/yuanchenqi/articles/6766020.html#_label5
http://www.cnblogs.com/wupeiqi/articles/5501365.html
內置模塊
import shutil
shutil.copyfileobj(fsrc, fdst[, length]) # 將文件內容拷貝到另外一個文件中 shutil.copyfile(src, dst) # 拷貝文件 shutil.copymode(src, dst) # 僅拷貝權限。內容、組、用戶均不變 shutil.copystat(src, dst) # 僅拷貝狀態的信息,包括:mode bits, atime, mtime, flags shutil.copy(src, dst) # 拷貝文件和權限 shutil.copy2(src, dst) # 拷貝文件和狀態信息 shutil.ignore_patterns(*patterns) # 做爲參數,傳入下面的copytree。忽略某些字段的文件。 shutil.copytree(src, dst, symlinks=False, ignore=None) # 遞歸的去拷貝文件夾 shutil.rmtree(path[, ignore_errors[, onerror]]) # 遞歸的去刪除文件 shutil.move(src, dst) # 遞歸的去移動文件,它相似mv命令,其實就是重命名。 shutil.make_archive(base_name, format,...) # 建立壓縮包並返回文件路徑,例如:zip、tar base_name: 壓縮包的文件名,也能夠是壓縮包的路徑。只是文件名時,則保存至當前目錄,不然保存至指定路徑, 如:www =>保存至當前路徑 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/ format: 壓縮包種類,「zip」, 「tar」, 「bztar」,「gztar」 root_dir: 要壓縮的文件夾路徑(默認當前目錄) owner: 用戶,默認當前用戶 group: 組,默認當前組 logger: 用於記錄日誌,一般是logging.Logger對象
1、copyfileobj shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w')) shutil.copyfileobj(open('old.xml','r'), open('new1.xml', 'a')) # 在後面追加 ''' [root@fat40 shutil_test]# ll 總用量 16 -rw-r--r--. 1 root root 42 4月 8 12:24 new1.xml -rw-r--r--. 1 root root 25 4月 8 12:24 new.xml -rw-r--r--. 1 admin admin 25 4月 8 12:17 old.xml -rw-r--r--. 1 root root 141 4月 8 12:23 test.py ''' 2、copyfile shutil.copyfile('old.xml', 'haha.xml') ''' -rw-r--r--. 1 root root 25 4月 8 12:28 haha.xml ''' 3、copymode # shutil.copymode('old.xml', 'new.xml') # 報錯,由於沒有該文件 shutil.copymode('old.xml', 'new2.xml') ''' -rwxrwxrwx. 1 root root 0 4月 8 12:33 new2.xml # mode換了 -rwxrwxrwx. 1 admin admin 25 4月 8 12:17 old.xml ''' 4、copystat shutil.copystat('old.xml', 'newnew.xml') ''' -rwxrwxrwx. 1 root root 0 4月 8 12:17 newnew.xml -rwxrwxrwx. 1 admin admin 25 4月 8 12:17 old.xml [root@fat40 shutil_test]# stat old.xml 文件:"old.xml" 大小:25 塊:8 IO 塊:4096 普通文件 設備:fd00h/64768d Inode:102072723 硬連接:1 權限:(0777/-rwxrwxrwx) Uid:( 1001/ admin) Gid:( 1001/ admin) 環境:unconfined_u:object_r:admin_home_t:s0 最近訪問:2018-04-08 12:17:53.843571572 +0800 最近更改:2018-04-08 12:17:03.979569888 +0800 最近改動:2018-04-08 12:33:53.440603988 +0800 建立時間:- [root@fat40 shutil_test]# stat newnew.xml 文件:"newnew.xml" 大小:0 塊:0 IO 塊:4096 普通空文件 設備:fd00h/64768d Inode:102072720 硬連接:1 權限:(0777/-rwxrwxrwx) Uid:( 0/ root) Gid:( 0/ root) 環境:unconfined_u:object_r:admin_home_t:s0 最近訪問:2018-04-08 12:17:53.843571572 +0800 最近更改:2018-04-08 12:17:03.979569888 +0800 最近改動:2018-04-08 12:41:51.862620149 +0800 建立時間:- ''' 5、copy shutil.copy("old.xml","new.xml") ''' -rwxrwxrwx. 1 root root 25 4月 8 13:02 new.xml -rwxrwxrwx. 1 admin admin 25 4月 8 12:17 old.xml ''' 6、copy2 shutil.copy2("old.xml","new.xml") ''' [root@fat40 shutil_test]# stat new.xml 文件:"new.xml" 大小:25 塊:8 IO 塊:4096 普通文件 設備:fd00h/64768d Inode:102072721 硬連接:1 權限:(0777/-rwxrwxrwx) Uid:( 0/ root) Gid:( 0/ root) 環境:unconfined_u:object_r:admin_home_t:s0 最近訪問:2018-04-08 13:02:38.419662258 +0800 最近更改:2018-04-08 12:17:03.979569888 +0800 最近改動:2018-04-08 13:05:25.222667893 +0800 建立時間:- [root@fat40 shutil_test]# stat old.xml 文件:"old.xml" 大小:25 塊:8 IO 塊:4096 普通文件 設備:fd00h/64768d Inode:102072723 硬連接:1 權限:(0777/-rwxrwxrwx) Uid:( 1001/ admin) Gid:( 1001/ admin) 環境:unconfined_u:object_r:admin_home_t:s0 最近訪問:2018-04-08 13:02:38.419662258 +0800 最近更改:2018-04-08 12:17:03.979569888 +0800 最近改動:2018-04-08 12:33:53.440603988 +0800 建立時間:- ''' 7、ignore_patterns 和 copytree shutil.copytree("a","new_folder",ignore=shutil.ignore_patterns("*.html","*.go")) # 不復制html和go文件 ''' [root@fat40 shutil_test]# tree a a ├── a.html ├── a.py ├── a.txt └── b ├── b.c ├── b.go ├── b.html └── c ├── c.html ├── c.txt ├── c.zzz └── old.xml 2 directories, 10 files [root@fat40 shutil_test]# tree new_folder/ new_folder/ ├── a.py ├── a.txt └── b ├── b.c └── c ├── c.txt ├── c.zzz └── old.xml 2 directories, 6 files ''' 8、rmtree shutil.rmtree("new_folder") ''' 刪除成功 ''' 9、move shutil.move("a","new_a") ''' drwxr-xr-x. 3 root root 50 4月 11 10:10 new_a ''' 10、make_archive ret = shutil.make_archive("hahaha","gztar",root_dir="new_a/b") print(ret) ''' root/shutil_test/hahaha.tar.gz -rw-r--r--. 1 root root 313 4月 11 10:23 hahaha.tar.gz ''' ret = shutil.make_archive("newfolder/hahaha","gztar",root_dir="new_a/b") print(ret) ''' /root/shutil_test/hahaha.tar.gz [root@fat40 shutil_test]# tree newfolder/ newfolder/ └── hahaha.tar.gz '''
import zipfile # 壓縮 z = zipfile.ZipFile('laxi.zip', 'w') z.write('a.log') z.write('data.data') z.close() # 解壓 z = zipfile.ZipFile('laxi.zip', 'r') z.extractall() z.close() import tarfile # 壓縮 tar = tarfile.open('your.tar','w') tar.add('a/b/bbs2.log', arcname='bbs2.log') tar.add('a/b/cmdb.log', arcname='cmdb.log') tar.close() # 解壓 tar = tarfile.open('your.tar','r') tar.extractall() # 可設置解壓地址 tar.close()
http://www.cnblogs.com/wupeiqi/articles/5501365.html
pip3 install pycrypto # 因爲 paramiko 模塊內部依賴pycrypto,因此先下載安裝pycrypto pip3 install paramiko
import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect("1.1.1.39",22,"root","toor") cmd = input(">>:") stdin,stdout,stderr = ssh.exec_command(cmd) print((stdout.read()+stderr.read()).decode("utf-8"),) ssh.close()
private_key_path = r'C:\Users\fat39\.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("1.1.1.39",22,"root",key) cmd = input(">>:") stdin,stdout,stderr = ssh.exec_command(cmd) print((stdout.read()+stderr.read()).decode("utf-8"),) ssh.close()
################ 上傳 ################### t = paramiko.Transport(("1.1.1.39",22)) t.connect(username="root",password="toor") sftp = paramiko.SFTPClient.from_transport(t) sftp.put("paramiko-master.zip","/home/fat39/paramiko-master.zip") t.close() ################ 下載 ################### t = paramiko.Transport(("1.1.1.39",22)) t.connect(username="root",password="toor") sftp = paramiko.SFTPClient.from_transport(t) sftp.get("/home/fat39/paramiko-master.zip","haha.zip") t.close()
############## 上傳 ################ private_key_path = r'C:\Users\fat39\.ssh\id_rsa' key = paramiko.RSAKey.from_private_key_file(private_key_path) t = paramiko.Transport(('1.1.1.39',22)) t.connect(username='root',pkey=key) sftp = paramiko.SFTPClient.from_transport(t) sftp.put('paramiko-master.zip','/home/fat39/haha.zip') ############## 下載 ################ private_key_path = r'C:\Users\fat39\.ssh\id_rsa' key = paramiko.RSAKey.from_private_key_file(private_key_path) t = paramiko.Transport(('1.1.1.39',22)) t.connect(username='root',pkey=key) sftp = paramiko.SFTPClient.from_transport(t) sftp.get('haha.zip','haha2.zip')
內置模塊
import time
時間相關的操做,時間有三種表示方式:
轉換示意圖
time() # 返回當前時間的時間戳 localtime([secs]) # 將一個時間戳轉換爲當前時區的struct_time。secs參數未提供,則以當前時間爲準。 gmtime([secs]) # 和localtime()方法相似,gmtime()方法是將一個時間戳轉換爲UTC時區(0時區)的struct_time。 mktime(t) # 將一個struct_time轉化爲時間戳。 asctime([t]) # 把一個表示時間的元組或者struct_time表示爲這種形式:'Sun Jun 20 23:21:05 1993'。若是沒有參數,將會將time.localtime()做爲參數傳入。 ctime([secs]) # 把一個時間戳(按秒計算的浮點數)轉化爲time.asctime()的形式。若是參數未給或者爲None的時候,將會默認time.time()爲參數。它的做用至關於time.asctime(time.localtime(secs))。 strftime(format[, t]) # 把一個表明時間的元組或者struct_time(如由time.localtime()和time.gmtime()返回)轉化爲格式化的時間字符串。若是t未指定,將傳入time.localtime()。若是元組中任何一個元素越界,ValueError的錯誤將會被拋出。 time.strptime(string[, format]) # 把一個格式化時間字符串轉化爲struct_time。實際上它和strftime()是逆操做。在這個函數中,format默認爲:"%a %b %d %H:%M:%S %Y"。 sleep(secs) # 線程推遲指定的時間運行,單位爲秒。 clock() # 這個須要注意,在不一樣的系統上含義不一樣。在UNIX系統上,它返回的是「進程時間」,它是用秒錶示的浮點數(時間戳)。而在WINDOWS中,第一次調用,返回的是進程運行的實際時間。而第二次以後的調用是自第一次調用之後到如今的運行時間,即兩次時間差。
%y 兩位數的年份表示(00-99) %Y 四位數的年份表示(000-9999) %m 月份(01-12) %d 月內中的一天(0-31) %H 24小時制小時數(0-23) %I 12小時制小時數(01-12) %M 分鐘數(00=59) %S 秒(00-59) %a 本地簡化星期名稱 %A 本地完整星期名稱 %b 本地簡化的月份名稱 %B 本地完整的月份名稱 %c 本地相應的日期表示和時間表示 %j 年內的一天(001-366) %p 本地A.M.或P.M.的等價符 %U 一年中的星期數(00-53)星期天爲星期的開始 %w 星期(0-6),星期天爲星期的開始 %W 一年中的星期數(00-53)星期一爲星期的開始 %x 本地相應的日期表示 %X 本地相應的時間表示 %Z 當前時區的名稱 %% %號自己
# 時間戳 time.time() # 1522935462.4855645 # 格式化時間 time.asctime() # 'Thu Apr 5 21:30:04 2018',參數是struct time,默認參數是time.localtime() time.asctime(time.localtime()) # 'Thu Apr 5 21:35:27 2018',參數是struct time time.asctime(time.localtime(150000)) # 'Sat Jan 3 01:40:00 1970',參數是struct time time.ctime() # 'Thu Apr 5 21:35:13 2018',參數是時間戳,默認參數是time.time() time.ctime(time.time()) # 'Thu Apr 5 21:35:06 2018',參數是時間戳 time.ctime(150000) # 'Thu Jan 1 08:25:00 1970',參數是時間戳 # struct time time.localtime() # 本地時間,timezone爲+8,之後默認使用本地時間。默認參數是time.time()。 # time.struct_time(tm_year=2018, tm_mon=4, tm_mday=5, tm_hour=18, tm_min=59, tm_sec=56, tm_wday=3, tm_yday=95, tm_isdst=0) t = time.localtime() # t.tm_year,t.tm_mon,t.mday。。。 time.localtime(12313123) # 參數是時間戳 time.struct_time(tm_year=1970, tm_mon=5, tm_mday=23, tm_hour=20, tm_min=18, tm_sec=43, tm_wday=5, tm_yday=143, tm_isdst=0) time.gmtime() # 格林威治時間,timezone爲0。默認參數是time.time() # 格式轉換 ################## 時間戳 <--> 結構化時間 ######################################## # 時間戳 轉換爲 struct time time.localtime(time.time()) # 時間戳轉換爲struct time,time.localtime(123123543) # struct time 轉換爲 時間戳 time.mktime(time.localtime()) # struct time轉換爲時間戳,本地時間轉爲時間戳 ################# 格式化時間 <--> 結構化時間 ###################################### time.strftime("%Y-%m-%d",time.localtime()) # '2018-04-05',struct time 轉換爲 結構化時間 # time.strftime('%y/%m/%d %H:%M:%S') # '18/04/05 19:05:18' time.strptime('2008-03-12',"%Y-%m-%d") # 將字符串時間轉換成結構化時間 time.strptime('Thu Apr 05 21:52:01 2018') # 默認格式"%a %b %d %H:%M:%S %Y",等於下面 time.strptime('Thu Apr 05 21:52:01 2018',"%a %b %d %H:%M:%S %Y") # "%a %b %d %H:%M:%S %Y" # 其餘 time.sleep(2)
內置模塊
import datetime
與time模塊同樣,時間分爲時間戳timestamp、格式化字符串format time、結構化時間struct time,轉換關係一直。
datetime說明
有以下5個類
################ date類 ################# # 類屬性 date.min: 返回 date(MINYEAR, 1, 1). date.max: 返回 date(MAXYEAR, 12, 31). date.year: 返回 年, MINYEAR和MAXYEAR之間 date.month: 返回 月, 1到12月之間 date.day: 返回 1到 n 之間. # 類方法 date.replace(year, month, day):返回一個相同值的data對象, 除了這些參數給關鍵字指定新的值. date.timetuple(): 返回一個time.struct_time對象. date.toordinal(): 返回一個Gregoian Calendar對象. date.weekday(): 返回day of the week. 星期一爲0,星期日爲6. date.isoweekday(): 返回day of the week. 星期一爲1,星期日爲7. date.isocalendar(): 返回一個三元組, (ISO year, ISO week number, ISO weekday). date.isoformat(): 返回 一個'YYYY-MM-DD'的字符串格式. date.ctime(): 返回一個字符串日期, d.ctime() 等同於 time.ctime(time.mktime(d.timetuple())). date.strftime(format): 返回一個字符串日期, 格式自定義. ################ datetime類 ################# # 類屬性 datetime.min: datetime(MINYEAR, 1, 1). datetime.max: datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999). # 實例屬性 datetime.year: 1 至 9999 datetime.month: 1 至 12 datetime.day: 1 至 n datetime.hour: In range(24). 0 至 23 datetime.minute: In range(60). datetime.second: In range(60). datetime.microsecond: In range(1000000). # 類方法 datetime.today(): 返回當前本地datetime.隨着 tzinfo None. 這個等同於datetime.fromtimestamp(time.time()). datetime.now([tz]): 返回當前本地日期和時間, 若是可選參數tz爲None或沒有詳細說明,這個方法會像today(). datetime.utcnow(): 返回當前的UTC日期和時間, 若是tzinfo None ,那麼與now()相似. datetime.fromtimestamp(timestamp[, tz]): 根據時間戳返回本地的日期和時間.tz指定時區. datetime.utcfromtimestamp(timestamp): 根據時間戳返回 UTC datetime. datetime.fromordinal(ordinal): 根據Gregorian ordinal 返回datetime. datetime.combine(date, time): 根據date和time返回一個新的datetime. datetime.strptime(date_string, format): 根據date_string和format返回一個datetime. # 實例方法 datetime.date(): 返回相同年月日的date對象. datetime.time(): 返回相同時分秒微秒的time對象. datetime.replace(kw): kw in [year, month, day, hour, minute, second, microsecond, tzinfo], 與date相似. ################ time類 ################# # 與上差很少
時區轉換
from datetime import datetime, timedelta, timezone utc_dt = datetime.utcnow().replace(tzinfo=timezone.utc) print(utc_dt) cn_dt = utc_dt.astimezone(timezone(timedelta(hours=8))) print(cn_dt) jan_dt = utc_dt.astimezone(timezone(timedelta(hours=9))) print(jan_dt) cn_2_jan_dt = cn_dt.astimezone(timezone(timedelta(hours=9))) print(cn_2_jan_dt) # 實測 if field.value > 958838733000: # 2000-01-01 dt = datetime.fromtimestamp(field.value / 1000) dt = dt.astimezone(timezone(timedelta(hours=8)))
# date類 date(year,month,day) datetime.date.today() # datetime.date(2018, 4, 5) 2018-04-05 # 初始化 td = datetime.date(2018,10,1) # td.year # 2018 int # td.__getattribute__("year") # td.month # 10 int # td.__getattribute__("month") # td.day # 1 int # td.__getattribute__("day") # 比較大小 a=datetime.date(2017,3,1) b=datetime.date(2017,3,15) a == b # a.__eq__(b) # False a >= b # a.__ge__(b) # False a > b # a.__gt__(b) # False a <= b # a.__le__(b) # True a < b # a.__lt__(b) # True a != b # a.__ne__(b) # True # 差值 a=datetime.date(2017,3,1) b=datetime.date(2017,3,15) a - b # a.__sub__(b) # datetime.timedelta(-14) b - a # a.__rsub__(b) # datetime.timedelta(14) # x = a - b # x.days # -14 int # ISO標準化日期 a = datetime.date(2017,3,22) a.isocalendar() # (2017, 12, 3) tuple 返回一個包含三個值的元組,三個值依次爲:year年份,week number週數,weekday星期數(週一爲1…週日爲7) a.isoformat() # '2017-03-22' str 返回符合ISO 8601標準 (YYYY-MM-DD) 的日期字符串; a.isoweekday() # 3 返回符合ISO標準的指定日期所在的星期數(週一爲1…週日爲7) a.weekday() # 2 與isoweekday(...)類似的還有一個weekday(...)方法,只不過是weekday(...)方法返回的週一爲 0, 週日爲 6 # 其餘 a = datetime.date(2017,3,22) a.timetuple() # 該方法爲了兼容time.localtime(...)返回一個類型爲time.struct_time的數組,但有關時間的部分元素值爲0 a.toordinal() # 返回公元公曆開始到如今的天數。公元1年1月1日爲1 datetime.date.resolution # date對象表示日期的最小單位。這裏是天。 datetime.date.fromtimestamp(time.time()) # datetime.date(2018, 4, 5) 根據給定的時間戮,返回一個date對象 datetime.date.today() # 返回當前日期 datetime.date.max # date類能表示的最大的年、月、日的數值 datetime.date.min # date類能表示的最小的年、月、日的數值 # 格式化 a = datetime.date(2017,3,22) a.strftime("%Y%m%d") # '20170322' a.__format__("%Y%m%d") # a.__format__('%Y-%m-%d') # '2017-03-22' <class 'str'> # a.__format__('%Y/%m/%d') # '2017/03/22' # a.__format__('%y/%m/%d') # '17/03/22' # a.__format__('%D') # '03/22/17' a.__str__() # '2017-03-22' str a.ctime() # 'Wed Mar 22 00:00:00 2017' b = datetime.date.today() # datetime.date(2018, 4, 5) b.ctime() # 'Thu Apr 5 00:00:00 2018'
import datetime # time類 a = datetime.time(12,20,59,899) # datetime.time(12, 20, 59, 899) a.hour # 12 a.__getattribute__("hour") # 比較大小 # 與date類一致 # 其餘 datetime.time.max # datetime.time(23, 59, 59, 999999) datetime.time.min # datetime.time(0, 0) datetime.time.resolution # datetime.timedelta(0, 0, 1) # 格式化 # 與date類一致,__format__(),strfttime() # ISO標準輸出 a = datetime.time(12,20,59,899) a.isoformat() # '12:20:59.000899'
import time import datetime # datetime類 # datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]]) a = datetime.datetime.now() # datetime.datetime(2018, 4, 5, 23, 9, 54, 826895) a.date() # 返回datetime對象的日期部分 datetime.date(2018, 4, 5) a.time() # 返回datetime對象的時間部分 datetime.time(16, 9, 33, 494248) a.utctimetuple() # 返回UTC時間元組 time.struct_time(tm_year=2018, tm_mon=4, tm_mday=5, tm_hour=23, tm_min=9, tm_sec=54, tm_wday=3, tm_yday=95, tm_isdst=0) datetime.datetime.utcnow() # datetime.datetime(2018, 4, 5, 15, 12, 17, 336671) # 格式化時間 <--> datetime datetime.datetime.strptime('2017-3-22 15:25','%Y-%m-%d %H:%M') # datetime.datetime(2017, 3, 22, 15, 25) datetime.datetime.strftime(datetime.datetime.now(),'%Y-%m-%d %X') # '2018-04-05 23:18:01' # datetime.datetime.strptime('2017-3-22 15:25','%Y-%m-%d %H:%M').timetuple() # struct time datetime.datetime.fromtimestamp(123123123) # datetime.datetime(1973, 11, 26, 8, 52, 3) datetime.datetime.utcfromtimestamp(time.time()) # datetime.datetime(2018, 4, 5, 15, 13, 38, 693083)
a = datetime.datetime.now() # datetime.datetime(2018, 4, 5, 23, 26, 18, 882579) tr = datetime.timedelta(days=10,hours=3) a - tr # datetime.datetime(2018, 3, 26, 20, 26, 18, 882579)
1.獲取當前日期時間
2.獲取上個月第一天和最後一天的日期
3.獲取時間差 時間差單位爲秒
4.計算當前時間向後8個小時的時間
5.計算上週一和週日的日期
6.計算指定日期當月最後一天的日期和本月天數
7.計算指定日期下個月當天的日期
8.得到本週一至今天的時間段並得到上週對應同一時間段
# 1.獲取當前日期時間 import datetime now = datetime.datetime.now() # datetime.datetime(2018, 4, 6, 0, 35, 22, 249989) today = datetime.date.today() # datetime.date(2018, 4, 6) now.date() # datetime.date(2018, 4, 6) now.time() # datetime.time(0, 35, 22, 249989) # 2.獲取上個月第一天和最後一天的日期 today = datetime.date.today() # datetime.date(2018, 4, 6) mlast_day = datetime.date(today.year, today.month, 1) - datetime.timedelta(1) # datetime.date(2018, 3, 31) mfirst_day = datetime.date(mlast_day.year, mlast_day.month, 1) # datetime.date(2018, 3, 1) # 3.獲取時間差 時間差單位爲秒 start_time = datetime.datetime.now() # datetime.datetime(2018, 4, 6, 0, 38, 30, 119113) end_time = datetime.datetime.now() # datetime.datetime(2018, 4, 6, 0, 38, 34, 10000) (end_time - start_time).seconds # 3 # 4.計算當前時間向後8個小時的時間 d1 = datetime.datetime.now() # datetime.datetime(2018, 4, 6, 0, 40, 9, 454170) d2 = d1 + datetime.timedelta(hours=8) # datetime.datetime(2018, 4, 6, 8, 40, 9, 454170) # 5.計算上週一和週日的日期 today = datetime.date.today() # datetime.date(2018, 4, 6) today_weekday = today.isoweekday() # 5 last_sunday = today - datetime.timedelta(days=today_weekday) # datetime.date(2018, 4, 1) last_monday = last_sunday - datetime.timedelta(days=6) # datetime.date(2018, 3, 26) # 6.計算指定日期當月最後一天的日期和本月天數 date = datetime.date(2017,12,20) def eomonth(date_object): if date_object.month == 12: next_month_first_date = datetime.date(date_object.year + 1, 1, 1) else: next_month_first_date = datetime.date(date_object.year, date_object.month + 1, 1) return next_month_first_date - datetime.timedelta(1) eomonth(date) # datetime.date(2017, 12, 31) eomonth(date).day # 31 # 7.計算指定日期下個月當天的日期 date = datetime.date(2017,10,31) # date = datetime.date(2017,12,20) def eomonth(date_object): if date_object.month == 12: next_month_first_date = datetime.date(date_object.year + 1, 1, 1) else: next_month_first_date = datetime.date(date_object.year, date_object.month + 1, 1) return next_month_first_date - datetime.timedelta(1) def edate(date_object): if date_object.month == 12: next_month_date = datetime.date(date_object.year+1, 1,date_object.day) else: next_month_first_day = datetime.date(date_object.year,date_object.month+1,1) if date_object.day > eomonth(next_month_first_day).day: next_month_date = datetime.date(date_object.year,date_object.month+1,eomonth(next_month_first_day).day) else: next_month_date = datetime.date(date_object.year, date_object.month+1, date_object.day) return next_month_date edate(date) # datetime.date(2018, 11, 30) # edate(date) # datetime.date(2018, 1, 20) # 8.得到本週一至今天的時間段並得到上週對應同一時間段 today = datetime.datetime.now() # datetime.datetime(2018, 4, 6, 1, 0, 44, 796079) this_monday = today - datetime.timedelta(days=today.isoweekday()-1) # datetime.datetime(2018, 4, 2, 1, 0, 44, 796079) last_monday = this_monday - datetime.timedelta(days=7) # datetime.datetime(2018, 3, 26, 1, 0, 44, 796079) last_weekday = today - datetime.timedelta(days=7) # datetime.datetime(2018, 3, 30, 1, 0, 44, 796079)
https://blog.csdn.net/cmzsteven/article/details/64906245