python之模塊

目錄

一、sys模塊html

二、os模塊node

三、subprocess模塊python

四、hashlib模塊linux

五、random模塊git

六、re模塊web

七、序列化之json模塊 、 pickle模塊 和 shelve模塊算法

八、configparser模塊shell

九、xml模塊數據庫

十、requests模塊json

十一、logging模塊

十二、shutil模塊

1三、paramiko模塊

1四、時間之time模塊 和 datetime模塊

1五、collections模塊

 

一、sys模塊

(1)安裝

  內置模塊

  import sys

(2)使用說明

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模塊

(3)驗證

待補充

(4)參考

官網

sys:https://docs.python.org/2/library/sys.html

二、os模塊

(1)安裝

  內置模塊

  import os

(2)使用說明

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模塊

(3)驗證

>>> 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
驗證

(4)參考

官網:

os:https://docs.python.org/2/library/os.html

三、subprocess模塊

(1)安裝

  內置模塊

  ipmort subprocess

(2)使用說明

  能夠執行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()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等 
Popen參數

 

child.wait()  # 等待子進程,相似於併發的join
child.poll() # 檢查子進程狀態
child.kill() # 終止子進程
child.send_signal() # 向子進程發送信號
child.terminate() # 終止子進程
ps: 子進程的PID存儲在child.pid
子進程方法

 

(3)驗證

  • call方法:父進程等待子進程執行命令,返回子進程執行命令的狀態碼,若是出現錯誤,不進行報錯。
  • check_call方法:父進程等待子進程執行命令,返回執行命令的狀態碼,若是出現錯誤,進行報錯【若是returncode不爲0,則舉出錯誤subprocess.CalledProcessError,該對象包含有returncode屬性,可用try…except…來檢查】

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
call方法(check_call用法一致,略),可運行系統命令,可直接從python跳轉到ssh
  • check_output方法:父進程等待子進程執行命令,返回子進程向標準輸出發送輸出運行結果,檢查退出信息,若是returncode不爲0,則舉出錯誤subprocess.CalledProcessError,該對象包含有returncode屬性和output屬性,output屬性爲標準輸出的輸出結果,可用try…except…來檢查。
>>> 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.
>>> 
check_output方法
  •  Popen方法:實際上,subprocess模塊中只定義了一個類: Popen。上面的幾個函數都是基於Popen()的封裝(wrapper)。從Python2.4開始使用Popen來建立進程,用於鏈接到子進程的標準輸入/輸出/錯誤中去,還能夠獲得子進程的返回值。這些封裝的目的在於讓咱們容易使用子進程。當咱們想要更個性化咱們的需求的時候,就要轉向Popen類,該類生成的對象用來表明子進程。與上面的封裝不一樣,Popen對象建立後,主程序不會自動等待子進程完成。咱們必須調用對象的wait()方法,父進程纔會等待 (也就是阻塞block)。
################## 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
'''
不等待子進程 與 子進程wait

 

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', '')
子進程文本流控制 stdin|stdout|stderr

(4)參考

參考:

http://www.cnblogs.com/wupeiqi/articles/5501365.html

http://www.javashuo.com/article/p-tmvlkdgo-c.html

四、hashlib模塊

(1)安裝

  內置模塊

  import hashlib

(2)使用說明

Python的hashlib提供了常見的摘要算法,如MD5,SHA1等等。

什麼是摘要算法呢?摘要算法又稱哈希算法、散列算法。它經過一個函數,把任意長度的數據轉換爲一個長度固定的數據串(一般用16進制的字符串表示)。

摘要算法就是經過摘要函數f()對任意長度的數據data計算出固定長度的摘要digest,目的是爲了發現原始數據是否被人篡改過。

摘要算法之因此能指出數據是否被篡改過,就是由於摘要函數是一個單向函數,計算f(data)很容易,但經過digest反推data卻很是困難。並且,對原始數據作一個bit的修改,都會致使計算出的摘要徹底不一樣。

  • python3,字符串須要encode("utf-8")
  • 內容太長時,可分次update,結果與一次過hash是同樣的
  • 支持算法:md5, sha1, sha224, sha256, sha384, sha512

(3)驗證

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驗證
#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('帳號不存在')
結合hashlib的簡單登陸
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

五、random模塊

(1)安裝

  內置模塊

  import random

(2)使用說明

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模塊

(3)驗證

>>> 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)
生成一個包含大寫字母A-Z和數字0-9的隨機4位驗證碼的程序
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))
生成指定長度字母數字隨機序列的代碼

(4)參考

參考:一、官網;二、別人的

六、re模塊

http://www.javashuo.com/article/p-mtdojeem-br.html

七、序列化之json模塊 、 pickle模塊 和 shelve模塊

什麼是序列化

咱們把對象(變量)從內存中變成可存儲或傳輸的過程稱之爲序列化,在Python中叫pickling,在其餘語言中也被稱之爲serialization,marshalling,flattening等等,都是一個意思。序列化以後,就能夠把序列化後的內容寫入磁盤,或者經過網絡傳輸到別的機器上。反過來,把變量內容從序列化的對象從新讀到內存裏稱之爲反序列化,即unpickling。

python用於序列化的兩個模塊

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

另,可以使用內置方法eval(xxxxx),但效果有限。

7.一、json模塊

(1)安裝

  內置模塊

  import json

(2)使用說明

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

dumps  # 將字典轉換成字符串,轉換後的字典中的元素是由雙引號表示的
dump  # dump方法接收一個文件句柄,直接將字典轉換成json字符串寫入文件
loads  # 將一個字符串轉換成字典類型
load  # load方法接收一個文件句柄,直接將文件中的json字符串轉換成數據結構返回
json

 

(3)驗證

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'}
json驗證
################ 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)
自定義json cls
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": "中國人"}
中文轉unicode(亂碼) 涉及ensure_ascii

(4)參考

7.二、pickle模塊

(1)安裝

  內置模塊

  import pickle

(2)使用說明

pickle支持全部python數據類型,pickle模塊提供了四個功能:dumps、dump、loads、load,與json類型

(3)驗證

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)
pickle驗證

(4)參考

7.三、shelve模塊

(1)安裝

  內容模塊

  import shelve

(2)使用說明

shelve也是python提供給咱們的序列化工具,比pickle用起來更簡單一些。
shelve只提供給咱們一個open方法,是用key來訪問的,使用起來和字典相似。

這個模塊有個限制,它不支持多個應用同一時間往同一個DB進行寫操做。因此當咱們知道咱們的應用若是隻進行讀操做,咱們可讓shelve經過只讀方式打開DB

(3)驗證

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
shelve驗證

(4)參考

八、configparser模塊

(1)安裝

  內置模塊

  import configparser

(2)使用說明

源文件指定格式

# 註釋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)
獲取指定節點下指定key的值
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')]
configparser模塊

(4)參考

九、xml模塊

(1)安裝

(2)使用說明

(3)驗證

(4)參考

十、requests模塊

http://www.javashuo.com/article/p-yoadyzgj-d.html

十一、logging模塊

(1)安裝

  內置模塊

  import logging

(2)使用說明

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'>)
我擦,忽然發現能夠直接實例化Logger而不用logging.getLogger

 

(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
logger.py
# -*- 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()
core.py
########### 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,以上均在屏幕上顯示出來
結果

 

(4)參考

http://www.cnblogs.com/yuanchenqi/articles/6766020.html#_label5

http://www.cnblogs.com/wupeiqi/articles/5501365.html

十二、shutil模塊

(1)安裝

  內置模塊

  import shutil

(2)使用說明

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對象
方法說明

(3)驗證

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

'''
shutil的驗證
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()
補充:shutil壓縮是調用ZipFile和TarFile

(4)參考

http://www.cnblogs.com/wupeiqi/articles/5501365.html

1三、paramiko模塊

(1)安裝

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

(2)使用說明

(3)驗證

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')
上傳/下載文件--祕鑰

(4)參考

1四、時間之time模塊 和 datetime模塊

14.一、time模塊

(1)安裝

  內置模塊

  import time

(2)使用說明

  時間相關的操做,時間有三種表示方式:

  • 時間戳timestamp               1522924616.3162944,1970年1月1日以後的秒,即:time.time()
  • 格式化的字符串format time    2018-04-05 18:36:56,    即:time.strftime('%Y-%m-%d')
  • 結構化時間struct time          time.struct_time(tm_year=2018, tm_mon=4, tm_mday=5, tm_hour=18, tm_min=36, tm_sec=56, tm_wday=3, tm_yday=95, tm_isdst=0),元組包含了:年、日、星期等... time.struct_time    即:time.localtime()

  轉換示意圖

  

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 當前時區的名稱
%% %號自己
格式化佔位符說明

(3)驗證

# 時間戳
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)
time模塊 驗證

(4)參考

14.二、datetime模塊

(1)安裝

  內置模塊

  import datetime

(2)使用說明

 

  與time模塊同樣,時間分爲時間戳timestamp、格式化字符串format time、結構化時間struct time,轉換關係一直。  

  datetime說明

  有以下5個類

  • class datetime.date: 一個理想化的日期, 提供year, month, day屬性
  • class datetime.time: 一個理想化的時間, 提供hour, minute, second, microsecond, tzinfo.
  • class datetime.datetime: 日期和時間的組合.提供year, month, day, hour, minute, second, microsecond, tzinfo.
  • class datetime.timedelta: 表達兩個date,time和datetime持續時間內的微妙差別.
  • class datetime.tzinfo: 時間對象的抽象基類.
################ 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)))

 

(3)驗證

# 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'
date類
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'
time類
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)
datetime類
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)
timedelta類

 

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)
一些題目

(4)參考

https://blog.csdn.net/cmzsteven/article/details/64906245

1五、collections模塊

http://www.cnblogs.com/fat39/p/7266344.html

相關文章
相關標籤/搜索