day 5 模塊導入、經常使用模塊os shutil sys commands subprocess hashlib json pickle zipfile traceback random dateti

os:css

 

 1 os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑
 2 os.chdir("dirname")  改變當前腳本工做目錄;至關於shell下cd
 3 os.curdir  返回當前目錄: ('.')
 4 os.pardir  獲取當前目錄的父目錄字符串名:('..')
 5 os.makedirs('dirname1/dirname2')    可生成多層遞歸目錄
 6 os.removedirs('dirname1')    若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
 7 os.mkdir('dirname')    生成單級目錄;至關於shell中mkdir dirname
 8 os.rmdir('dirname')    刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
 9 os.listdir('dirname')    列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
10 os.remove()  刪除一個文件
11 os.rename("oldname","newname")  重命名文件/目錄
12 os.stat('path/filename') 獲取文件/目錄信息 13 os.sep    輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"
14 os.linesep    輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n"
15 os.pathsep    輸出用於分割文件路徑的字符串
16 os.name    輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix'
17 os.system("bash command")  運行shell命令,直接顯示
18 os.environ  獲取系統環境變量
19 os.path.abspath(path)  返回path規範化的絕對路徑
20 os.path.split(path)  將path分割成目錄和文件名二元組返回
21 os.path.dirname(path) 返回path的目錄。其實就是os.path.split(path)的第一個元素 22 os.path.basename(path)  返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
23 os.path.exists(path) 若是path存在,返回True;若是path不存在,返回False 24 os.path.isabs(path)  若是path是絕對路徑,返回True
25 os.path.isfile(path)  若是path是一個存在的文件,返回True。不然返回False
26 os.path.isdir(path)  若是path是一個存在的目錄,則返回True。不然返回False
27 os.path.join(path1[, path2[, ...]]) 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 28 os.path.getatime(path)  返回path所指向的文件或者目錄的最後存取時間
29 os.path.getmtime(path)  返回path所指向的文件或者目錄的最後修改時間

 

 1 import os
 2 
 3 print(__file__)
 4 print(os.path.dirname(__file__))   # 取python文件路徑名、目錄名
 5 print(os.path.dirname(os.path.dirname(__file__)))  # 返回上一級目錄
 6 print(os.path.basename(__file__))  # 取python文件文件名
 7 # 輸出:
 8 C:/Users/w/PycharmProjects/python/hashlib/0718.py
 9 C:/Users/w/PycharmProjects/python/hashlib
10 C:/Users/w/PycharmProjects/python
11 0718.py
 1 # -*- coding: utf-8 -*-
 2 
 3 import os
 4 import sys
 5 #from bin import s3
 6 
 7 print(os.path.dirname(__file__))
 8 print(os.path.basename(__file__))
 9 
10 p1 = os.path.dirname(__file__)
11 p2 = 'bin'
12 p = os.path.join(p1, p2)
13 print(p)
14 
15 sys.path.append(p)  # 相比於下面的添加路徑方法,好處在於改了路徑名,不需改代碼
16 #sys.path.append(r'C:\Users\w\PycharmProjects\python\hashlib\bin')
17 
18 for i in sys.path:   # 默認根據列表中的路徑找模塊
19    print(i)
20 print('-------------------------')
21 
22 import s3
23 s3.test()
24 
25 輸出:
26 C:/Users/w/PycharmProjects/python/hashlib
27 0718.py
28 C:/Users/w/PycharmProjects/python/hashlib\bin
29 C:\Users\w\PycharmProjects\python\hashlib
30 C:\Users\w\PycharmProjects
31 C:\Users\w\AppData\Local\Programs\Python\Python35\python35.zip
32 C:\Users\w\AppData\Local\Programs\Python\Python35\DLLs
33 C:\Users\w\AppData\Local\Programs\Python\Python35\lib
34 C:\Users\w\AppData\Local\Programs\Python\Python35
35 C:\Users\w\AppData\Local\Programs\Python\Python35\lib\site-packages
36 C:/Users/w/PycharmProjects/python/hashlib\bin
37 -------------------------
38 =======in s3========
模塊路徑添加方法

 

1 import os
2 import sys
3 sys.path.append(os.path.join(os.path.dirname(__file__), 'bin'))
一行代碼添加路徑

 

1 import sys
2 import os
3 
4 #導入父目錄下的另外一個目錄到系統路徑sys.path
5 
6 sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'day3'))

 

 

 

目錄遍歷:html

os.walk(top, topdown=True, onerror=None, followlinks=False)
能夠獲得一個三元tupple(dirpath, dirnames, filenames),
第一個爲起始路徑,第二個爲起始路徑下的文件夾,第三個是起始路徑下的文件。
dirpath 是一個string,表明每個基於top的目錄路徑,
dirnames 是一個list,包含了dirpath下全部子目錄的名字。
filenames 是一個list,包含了非目錄文件的名字。
這些名字不包含路徑信息,若是須要獲得基於top的全路徑,須要使用os.path.join(dirpath, name).java

例:node

#!/usr/bin/python
# -*- coding: UTF-8 -*-python

import osweb

a = '/home/yumiao/sp2p_web-20170413-01'算法

for dirpath,dirnames,filenames in os.walk('/home/yumiao/sp2p_web-20170413-01'):
    for filename in filenames:
    #遍歷全部文件(絕對路徑)
        print dirpath+filenameshell

for dir in dirnames:
    #遍歷全部目錄
    print dirapache

 

# 獲取一個目錄下全部文件,不包括空目錄
import os
for dirpath,dirnames,filenames in os.walk('/root'):
    for filename in filenames:
        print dirpath+'/'+filename

 

[root@centos6 yumiao]# tree -L 1 /data/apache-tomcat
/data/apache-tomcat
├── apache-tomcat-sp2p-web-1025
├── tomcat-cms-app-1038
├── tomcat-jenkins-2025
├── tomcat-jenkins-2026
└── tomcat-mobi_server-1029json

for dirpath,dirnames,filenames in os.walk(rootdir):
# for filename in filenames:
# directory = dirpath.split(rootdir)
# print directory
#for file in filenames:
# print dirpath+file
#print dirnames
#print dirpath
print filenames
if count > 4:
break
count += 1

 

 


dirpath: 是字符串,是目錄的路徑

/data/apache-tomcat
/data/apache-tomcat/tomcat-jenkins-2026
/data/apache-tomcat/tomcat-jenkins-2026/logs
/data/apache-tomcat/tomcat-jenkins-2026/bin
/data/apache-tomcat/tomcat-jenkins-2026/webapps
/data/apache-tomcat/tomcat-jenkins-2026/webapps/ROOT

 

dirnames: 是一個列表,dirpath中(除了.和..)包含了全部子目錄名字
['tomcat-jenkins-2026', 'tomcat-jenkins-2025', 'tomcat-cms-app-1038', 'tomcat-mobi_server-1029', 'apache-tomcat-sp2p-web-1025']
['logs', 'bin', 'webapps', 'work', 'lib', 'conf', 'temp']
[]
[]
['ROOT']
['images', 'jsbundles', 'help', 'executable', 'scripts', 'WEB-INF', 'css', 'META-INF']

 

filenames:是一個列表,包含了dirpath路徑下全部非目錄的文件名
[]
['NOTICE', 'RELEASE-NOTES', 'LICENSE', 'RUNNING.txt']
['catalina.2017-02-07.log', 'catalina.2017-02-13.log', 'catalina.2017-02-14.log', 'catalina.2017-02-12.log', 'access_log.2017-02-07.txt', 'access_log.2017-02-08.txt', 'host-manager.2017-02-07.log', 'catalina.2017-02-11.log', 'catalina.2017-02-09.log', 'catalina.2017-02-10.log', 'catalina.out', 'catalina.2017-02-08.log', 'manager.2017-02-07.log', 'localhost.2017-02-07.log']
['configtest.bat', 'startup.bat', 'version.bat', 'tool-wrapper.sh', 'version.sh', 'catalina-tasks.xml', 'bootstrap.jar', 'configtest.sh', 'digest.bat', 'tomcat-juli.jar', 'catalina.bat', 'tool-wrapper.bat', 'startup.sh', 'setclasspath.sh', 'catalina.sh', 'install.sh', 'setclasspath.bat', 'daemon.sh', 'shutdown.sh', 'commons-daemon-native.tar.gz', 'commons-daemon.jar', 'digest.sh', 'shutdown.bat', 'tomcat-native.tar.gz', 'run.sh']
['jenkins.war']
['LogFileOutputStream$2.class', 'MainDialog$1$1.class', 'MainDialog.class', 'dc-license.txt', 'winstone.jar', 'robots.txt', 'Main.class', 'LogFileOutputStream$1.class', 'JNLPMain.class', 'favicon.ico', 'ColorFormatter.class', 'LogFileOutputStream.class', 'index.jsp', 'Main$FileAndDescription.class', 'MainDialog$1.class']

 


walk(top, topdown=True, onerror=None, followlinks=False)
Directory tree generator.

For each directory in the directory tree rooted at top (including top
itself, but excluding '.' and '..'), yields a 3-tuple

dirpath, dirnames, filenames

dirpath is a string, the path to the directory. dirnames is a list of
the names of the subdirectories in dirpath (excluding '.' and '..').
filenames is a list of the names of the non-directory files in dirpath.
Note that the names in the lists are just names, with no path components.
To get a full path (which begins with top) to a file or directory in
dirpath, do os.path.join(dirpath, name).

 

 

 

 

 

 

 

 

# os.system(在python腳本中執行shell命令)

#  Execute the command (a string) in a subshell.

# eg:

a = os.system('echo "this is py"')
print a

 

注意:

filename = 'demo2'
path = './'

os.system('rm -rf '+path+filename+'/*')  【-rf 後面必定要留一個空格出來不然會報錯】

os.system()函數沒法返回命令的輸出。只會返回C函數運行成功與否的0或其餘值。



 

 

 

 

判斷路徑或文件

 

os.path.join:join(a, *p)
Join two or more pathname components, inserting '/' as needed.If any component is an absolute path, all previous path components will be discarded.
An empty last part will result in a path that ends with a separator.

 

os.path.isabs(...)      # 判斷是否絕對路徑 Test whether a path is absolute
os.path.exists(...)     # 判斷是否真實存在 exists(path) Test whether a path exists. Returns False for broken symbolic links
os.path.isdir(...)     # 判斷是不是個目錄 Return true if the pathname refers to an existing directory
os.path.isfile(...)    # 判斷是不是個文件 isfile(path) Test whether a path is a regular file
注意: 把兩個路徑合成一個時,不要直接拼字符串,而要經過 os.path.join(part1,part2) 函數,這樣能夠正確處理不一樣操做系統的路徑分隔符。在Linux/Unix/Mac下,os.path.join()返回這樣的字符串 part1/part2而Windows下會返回這樣的字符串: part1\part2

 

 

 


路徑名、文件名分隔
os.path.split(...) # 分隔目錄和文件名/文件夾名 split(p) Split a pathname. Returns tuple "(head, tail)" where "tail" is everything after the final slash. Either part may be empty.
os.path.splitdrive(...) # 分隔盤符(windows系統) splitdrive(p) Split a pathname into drive and path. On Posix, drive is always empty.
os.path.splitext(...) # 分隔文件和擴展名 splitext(p) Split the extension from a pathname. Extension is everything from the last dot to the end, ignoring leading dots. Returns "(root, ext)"; ext may be empty.

 

這些合併、拆分路徑的函數並不要求目錄和文件要真實存在,它們只對字符串進行操做。

 

 

 


工做目錄及建立文件夾操做
os.getcwd()      # 獲取當前工做目錄
os.chdir(...)     # 改變工做目錄 chdir(path)
os.listdir(...)    # 列出目錄下的文件 listdir(path)
os.mkdir(...)     # 建立單個目錄 mkdir(path [, mode=0777])#測試時好像不支持權限參數     注意:建立多級用 os.makedirs()
os.makedirs(...)   # 建立多級目錄 makedirs(path [, mode=0777]) mkdir recursive.

 

建立文件夾可能會出錯,緣由具體有:(1) path 已存在時(無論是文件仍是文件夾) (2) 驅動器不存在 (3) 磁盤已滿 (4) 磁盤是隻讀的或沒有寫權限

 

 

 

刪除文件夾/文件

 

os.rmdir(...)         # 刪除空文件夾 注意:必須爲空文件夾 如需刪除文件夾及其下全部文件,需用 shutil
os.remove(...) # 刪除單一文件
shutil.rmtree(...) # 刪除文件夾及其下全部文件

 

tip1:清空指定文件夾下全部文件的方法

須要在執行某些代碼前清空指定的文件夾,若是直接用os.remove(),可能出現因文件夾中文件被佔用而沒法刪除,解決方法也很簡單,先強制刪除文件夾,再從新建同名文件夾便可

  1. import shutil  
  2. shutil.rmtree('要清空的文件夾名')  
  3. os.mkdir('要清空的文件夾名')  

 

產生異常的可能緣由: (1) 路徑不存在 (2) 路徑子目錄中有文件或下級子目錄(os.rmdir) (3) 沒有操做權限或只讀

 tip2:把一個文件從一個文件夾移動到另外一個文件夾,並同時重命名,用shutil:

   shutil.move('原文件夾/原文件名','目標文件夾/目標文件名')  

 

 

 

 

重命名文件夾/文件
可對某一文件或文件夾重命名 os.rename(oldfileName, newFilename)
注意:新文件的擴展名不能遺漏,理論上須要保持類型一致;但這也不失爲改文件類型的一種方式(至關於直接改文件的擴展名)

 

 

 

 

shutil

複製、移動文件夾/文件 :(new不指定路徑,默認放到家目錄)
shutil.copyfile("old","new")      # (不copy權限)複製文件,都只能是文件 copyfile(src, dst) 注意:不會保持源文件權限,若是存在new會強制覆蓋!!!
shutil.copytree("old","new")     # 複製文件夾,都只能是目錄,且new必須不存在 Recursively copy a directory tree using copy2() 保持源文件信息
shutil.copy("old","new")     # (copy權限)複製文件/文件夾,複製 old 爲 new(new是文件,若不存在,即新建,存在則覆蓋!),複製 old 爲至 new 文件夾(文件夾已存在),至關於 cp src dst
shutil.move("old","new")      # 移動文件/文件夾至 new 文件夾中 同Unix下的mv命令
shutil.copy2(src, dst) #只能複製文件,只保留stat信息 Copy data and all stat info ("cp -p src dst") The destination may be a directory

 

 1 import shutil
 2 
 3 # 高級的 文件、文件夾、壓縮包 處理模塊
 4 shutil.copyfileobj(open('log.log', 'r'), open('new_log.log', 'w')) # 將文件內容拷貝到另外一個文件中
 5 
 6 # 僅拷貝權限。內容、組、用戶均不變 shutil.copymode(src, dst)
 7 shutil.copymode('f1.log', 'f2.log')
 8 
 9 # 僅拷貝狀態的信息,包括:mode bits, atime, mtime, flags  shutil.copystat(src, dst)
10 shutil.copystat('f1.log', 'f2.log')
11 
12 # 遞歸的去拷貝文件夾 shutil.copytree(src, dst, symlinks=False, ignore=None)
13 shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
14 # 拷貝源文件,仍是隻拷貝軟鏈接,用symlinks參數調節
15 shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
16 
17 # 建立壓縮包並返回文件路徑,例如:zip、tar
18 # shutil.make_archive(base_name, format,...)
19 
20 base_name: 壓縮包的文件名,也能夠是壓縮包的路徑。只是文件名時,則保存至當前目錄,不然保存至指定路徑,
21 如:www                        =>保存至當前路徑
22 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
23 format:    壓縮包種類,「zip」, 「tar」, 「bztar」,「gztar」
24 root_dir:    要壓縮的文件夾路徑(默認當前目錄)
25 owner:    用戶,默認當前用戶
26 group:    組,默認當前組
27 logger:    用於記錄日誌,一般是logging.Logger對象
28 
29 #將 /Users/wupeiqi/Downloads/test 下的文件打包放入www.gztar文件,放置當前程序目錄
30 ret = shutil.make_archive("www", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
31 
32 #將 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目錄
33 ret = shutil.make_archive("/Users/wupeiqi/www", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
34 
35 # shutil 對壓縮包的處理是調用 ZipFile 和 TarFile 兩個模塊來進行的,詳細:
36 #處理zip包
37 import zipfile
38 # 壓縮
39 z = zipfile.ZipFile('laxi.zip', 'w')  # w方式建立,默認清空壓縮包中的文件
40 z.write('a.log')
41 z.write('data.data')  # 添加單獨的文件到壓縮包中
42 z.close()
43 
44 # 解壓
45 z = zipfile.ZipFile('laxi.zip', 'r')
46 r = z.namelist()  # 獲取壓縮文件列表
47 z.extractall()   # 沒有文件名,默認解壓所有文件,有文件名,則解壓單獨文件
48 z.close()
49 
50 #處理tar包
51 import tarfile
52 # 壓縮
53 tar = tarfile.open('your.tar','w')
54 tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log')
55 tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log')
56 tar.close()
57 
58 # 解壓
59 tar = tarfile.open('your.tar','r')
60 tar.extractall()  # 可設置解壓地址
61 tar.close()

 

 

 

 

commands模塊
commands.getoutput('shell command') # 執行shell命令,返回結果(string類型),忽略返回值
commands.getstatusoutput('shell command') # 執行shell命令, 返回兩個元素的元組tuple(status, result),status爲int類型,result爲string類型。返回結果包含標準輸出和標準錯誤.
commands.getstatus('file') # 該函數已被python丟棄,不建議使用,它返回 ls -ld file 的結果(String)

以上執行shell命令的相關的模塊和函數的功能均在 subprocess 模塊中實現,並提供了更豐富的功能

 

subprocess模塊

 

 1 import subprocess
 2 
 3 
 4 call方法:執行命令,返回狀態碼
 5 ret = subprocess.call(["ls", "-l"], shell=False)  # shell爲False時,會把命令解析爲一個字符,因此要以列表形式輸入
 6 ret1 = subprocess.call("ls -l", shell=True)
 7 
 8 # check_call方法:執行命令,若是執行狀態碼是 0 ,則返回0,不然拋異常
 9 subprocess.check_call(["ls", "-l"])
10 subprocess.check_call("exit 1", shell=True)
11 
12 
13 # check_output:執行命令,若是狀態碼是 0 ,則返回執行結果,不然拋異常
14 subprocess.check_output(["echo", "Hello World!"])
15 subprocess.check_output("exit 1", shell=True)
16 
17 
18 # Popen方法:用於執行復雜的系統命令,程序不會阻塞,而subprocess.run是阻塞的
19 參數:
20 args:shell命令,能夠是字符串或者序列類型(如:list,元組)
21 bufsize:指定緩衝。0 無緩衝,1 行緩衝,其餘 緩衝區大小,負值 系統緩衝
22 stdin, stdout, stderr:分別表示程序的標準輸入、輸出、錯誤句柄
23 preexec_fn:只在Unix平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行以前被調用
24 close_sfs:在windows平臺下,若是close_fds被設置爲True,則新建立的子進程將不會繼承父進程的輸入、輸出、錯誤管道。
25 因此不能將close_fds設置爲True同時重定向子進程的標準輸入、輸出與錯誤(stdin, stdout, stderr)。
26 shell:同上
27 cwd:用於設置子進程的當前目錄
28 env:用於指定子進程的環境變量。若是env = None,子進程的環境變量將從父進程中繼承。
29 universal_newlines:不一樣系統的換行符不一樣,True -> 贊成使用 \n
30 startupinfo與createionflags只在windows下有效
31 將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等
32 
33 
34 # 執行普通命令:
35 ret1 = subprocess.Popen(["mkdir","t1"])
36 ret2 = subprocess.Popen("mkdir t2", shell=True)
37 
38 
39 終端輸入的命令分爲兩種:
40 
41 輸入便可獲得輸出,如:ifconfig
42 輸入進行某環境,依賴再輸入,如:python ,進入python交互環境
43 
44 # 經過Popen建立目錄:
45 obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)  # 用於設置子進程的當前目錄
46 
47 # 經過subprocess.PIPE進行交互輸入命令、讀取(正確/錯誤)結果[由於subprocess是新啓動一個進程,若是主進程想要獲取子進程的結果(進程間通訊),就要經過管道/socket來實現:即PIPE]
48 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
49 obj.stdin.write("print(1)\n")
50 obj.stdin.write("print(2)")
51 obj.stdin.close()
52 
53 cmd_out = obj.stdout.read()
54 obj.stdout.close()
55 cmd_error = obj.stderr.read()
56 obj.stderr.close()
57 
58 print(cmd_out)
59 print(cmd_error)
60 
61 # 經過communicate屢次單條命令交互
62 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
63 obj.stdin.write("print(1)\n")
64 obj.stdin.write("print(2)")
65 
66 out_error_list = obj.communicate()   # 至關於去讀管道中的內容,obj.stdout.read(),obj.stderr.read(),並把讀到的內容進行拼接,其中包含輸出和錯誤輸出
67 print(out_error_list)
68 
69 
70 # 單條命令直接經過communicate執行,並從中獲取結果
71 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
72 out_error_list = obj.communicate('print("hello")')
73 print(out_error_list)

  

subprocess 
該子模塊容許你建立新的流程,鏈接到它們的輸入/輸出/錯誤管道,並獲取他們的返回值。該模塊打算替換多箇舊的模塊和功能:os.system   和  os.spawn *
使用subprocess時建議使用run()函數去處理全部它能夠處理的狀況,由於高級用法能夠直接使用底層POPEN接口。
run()函數是Python 3.5中新添加的。
使用方法:
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False)
args    該參數用於啓動進程。這多是一個列表或一個字符串。

returncode   該參數表示子進程的退出狀態。
一般狀況下,0做爲退出狀態代表它成功運行。
負值-N代表子進程被信號N終止(僅POSIX)。

stdout  該參數表示標準輸出
從子過程當中捕獲標準輸出。一個字節序列,或字符串 ()若是運行一個字符串被稱爲與universal_newlines = TRUE。無若是stdout沒有抓獲。

        若是您運行進程與標準錯誤= subprocess.STDOUT,輸出和錯誤將在此屬性相結合,和stderr將是無。

    標準錯誤

        從子過程當中捕獲標準錯誤。一個字節序列,或()若是運行一個字符串被稱爲與universal_newlines = TRUE。無標準錯誤,若是沒有抓獲。

    check_returncode()

        若是返回碼不爲零,養CalledProcessError。


先看個例子:
>>> import subprocess
>>> subprocess.run(["ls"])
run_server.py    # ls命令返回的結果
CompletedProcess(args=['ls'], returncode=0)  # run函數返回的結果
>>> subprocess.run(["ls", "-l"])  # 這個和上面的相似
總用量 4
-rw-r--r-- 1 root root 266 9月  22 14:35 run_server.py
CompletedProcess(args=['ls', '-l'], returncode=0)

>>> subprocess.run(["ls"],stdout=subprocess.PIPE)  # 加上stdout參數以後,系統命令返回的結果就不會輸出了
CompletedProcess(args=['ls'], returncode=0, stdout=b'run_server.py\n')

>>> a = subprocess.run(["ls"],stdout=subprocess.PIPE)  
>>> print(a)
CompletedProcess(args=['ls'], returncode=0, stdout=b'run_server.py\n')
>>> print(a.stdout,a.args,a.returncode)  # 能夠對返回值進行操做
b'run_server.py\n' ['ls'] 0
subprocess run方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import subprocess
import sys
import smtplib
import string
import time
import subprocess
import datetime
from smtplib import SMTP_SSL
from email.header import Header
from email.mime.text import MIMEText
import socket


#logging.basicConfig(filename='process_log',
logging.basicConfig(
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10)


file_1_1 = logging.FileHandler('/var/log/process_log.log', 'a', encoding='utf-8')                          
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")    
file_1_1.setFormatter(fmt)

logger1 = logging.Logger('recommend-node1-doyo-feedstream-go', level=logging.ERROR)  
logger1.addHandler(file_1_1)                        

fail_check = 0
check_interval = 5

reload(sys)
sys.setdefaultencoding('utf-8')
text = ''
datetime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
hostname = socket.gethostname()


def S_Mail(text):
    HOST = "smtp.exmail.qq.com"
    SUBJECT = 'DOYO Process Monitor'.decode('utf-8').encode('gbk')
    TO = 'whisky@doyo.tv'
    FROM = "monitor@douyu.tv"
    BODY = string.join((
                    "FROM: %s" % FROM,
                    "To: %s"  % TO,
                    "Subject: %s" %SUBJECT,
                    "",
                    text
                    ),"\r\n")
    smtp = smtplib.SMTP_SSL(HOST,465)
    smtp.ehlo()
    smtp.login("monitor@douyu.tv","Hello123456")
    smtp.sendmail(FROM,[TO],BODY)
    smtp.quit()

    with open('/tmp/py_Email.log','a') as f:
        date=time.strftime("%y-%m-%d %H:%M:%S")
        str = date + "    " + TO +"    " + SUBJECT + "\r\n" + "\n"
        str1 = str.decode('gbk').encode('utf-8')
#       print("%s" %str1)
        f.write(str1)


def monitor_process(key_word, cmd, fail_check):
    p1 = subprocess.Popen(['ps', '-ef'], stdout=subprocess.PIPE)
    p2 = subprocess.Popen(['grep', key_word], stdin=p1.stdout, stdout=subprocess.PIPE)
    p3 = subprocess.Popen(['grep', '-v', 'grep'], stdin=p2.stdout, stdout=subprocess.PIPE)
    p4 = subprocess.Popen(['egrep', '-v', 'doyo-feedstream-go.log|su www'], stdin=p3.stdout, stdout=subprocess.PIPE)

    lines = p4.stdout.readlines()
    if len(lines) > 0:  # process is ok
        return
    else:
        time.sleep(check_interval)
    fail_check += 1
        if fail_check < 4:
        return monitor_process(key_word, cmd, fail_check)
        else:
            pass
    sys.stderr.write('process[%s] is lost, run [%s]\n' % (key_word, cmd))
    logger1.critical('process[%s] is lost, run [%s]\n' % (key_word, cmd))
    #subprocess.call(cmd,env={'JAVA_HOME': '/usr/java/jdk1.8.0_181/'}, shell=True)
    subprocess.call(cmd, shell=True)
    msg = 'hostname:{0}   msg: process:{1} is lost, run {2} , time: {3}'.format(hostname, key_word, cmd, datetime).decode('utf-8').encode('gbk')
    S_Mail(msg)


if __name__ == '__main__':
    #monitor_process('doyo-feedstream-go', 'cd /data/doyo-feedstream-go/; su www -s nohup ./doyo-feedstream-go &', fail_check)
    monitor_process('doyo-feedstream-go', 'cd /data/doyo-feedstream-go/; su www -s ./doyo-feedstream-go &> /dev/null &', fail_check) # no startup.sh,use non-nohup , command finished,su www will exit
subprocess進程檢測腳本

 

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

 

 

 

 

 

sys模塊

1 sys.argv           命令行參數List,第一個元素是程序自己路徑
2 sys.exit(n)        退出程序,正常退出時exit(0)
3 sys.version        獲取Python解釋程序的版本信息
4 sys.maxint         最大的Int值
5 sys.path           返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
6 sys.platform       返回操做系統平臺名稱
7 sys.stdout.write('please:')
8 val = sys.stdin.readline()[:-1]

 

 

sys.argv(http://www.cnblogs.com/aland-1415/p/6613449.html)

 

0426.py腳本以下:

import sys
a = sys.argv[0]
b = sys.argv[1]
c = sys.argv[1:]

print a
print b
print c

 

執行腳本:

/home/yumiao/0426.py  2 Obama vivo trump

輸出:

/home/yumiao/0426.py
2
['2', 'Obama', 'vivo', 'trump']

 

 

hashlib模塊

 

python3中的hashlib
1. md5加密
hash = hashlib.md5()
hash.update('admin'.encode('utf-8'))
print(hash.hexdigest())
21232f297a57a5a743894a0e4a801fc3

2. sha1加密
hash = hashlib.sha1()
hash.update('admin'.encode('utf-8'))
print(hash.hexdigest())
d033e22ae348aeb5660fc2140aec35850c4da997

3. sha256加密
hash = hashlib.sha256()
hash.update('admin'.encode('utf-8'))
print(hash.hexdigest())
8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918

4. sha384加密
 hash = hashlib.sha384()
hash.update('admin'.encode('utf-8'))
print(hash.hexdigest())
9ca694a90285c034432c9550421b7b9dbd5c0f4b6673f05f6dbce58052ba20e4248041956ee8c9a2ec9f10290cdc0782

5. sha512加密
hash = hashlib.sha512()
hash.update('admin'.encode('utf-8'))
print(hash.hexdigest())
c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec

6. ‘加鹽’加密
  以上加密算法雖然很厲害,但仍然存在缺陷,經過撞庫能夠反解。因此必要對加密算法中添加自定義key再來作加密。
1 ######  md5 加密 ############
hash = hashlib.md5('python'.encode('utf-8'))
hash.update('admin'.encode('utf-8'))
print(hash.hexdigest())
75b431c498b55557591f834af7856b9f

7. hmac加密
  hmac內部對咱們建立的key和內容進行處理後在加密
import hmac
h = hmac.new('python'.encode('utf-8'))
h.update('helloworld'.encode('utf-8'))
print(h.hexdigest())
b3b867248bb4cace835b59562c39fd55

 

json模塊:

(json的loads,dumps方法)

 1 import json
 2 
 3 s = '{"desc":"invilad-citykey","status":1002}'  # 這種形似列表或字典或元組的字符串(s是由單引號括起來的字符串),內部元素若是是字符串,必需要加雙引號(單引號會報錯,若是交給json處理)
 4 l = '[11, 22, 33, 44]'
 5 result = json.loads(s)  # 將一個形似列表或字典或元組的字符串,轉換成列表或字典(前提,字符串必須符合列表或字典或元組的的格式)
 6 result2 = json.loads(l)
 7 print(result, type(result))
 8 print(result2, type(result2))
 9 
10 # 輸出:
11 {'desc': 'invilad-citykey', 'status': 1002} <class 'dict'>
12 [11, 22, 33, 44] <class 'list'>
13 
14 dic = {'first': 1, "second": 2}
15 user_list = ['peter', 'john']
16 m = json.dumps(dic)
17 n = json.dumps(user_list)
18 print(m, type(m))
19 print(n, type(n))
20 #輸出
21 {"first": 1, "second": 2} <class 'str'>
22 ["peter", "john"] <class 'str'>
23 
24 小結:
25 json.loads()  # 將字符串-->python基本數據類型(內部必須是雙引號,不然報錯)
26 json.dumps()  # 將python基本數據類型-->字符串
27 
注意:元組在loads時會出錯,元組在dumps時會變成列表。由於只有字典、列表是通用數據類型
json:本質就是字符串(內容比較特殊,是列表、字典、元組)
http請求響應內容是字符串,若是要讓python處理,需用json的loads方法。

 

json的load,dump:做用,轉換以後寫到文件中(不經常使用)

 1 import json
 2 a = '{"whisky": 666, "tom": 2333, "peter": "ok"}'
 3 
 4 dic = {"whisky": 666, "tom": 2333, "peter": "ok"}
 5 json.dump(a, open('db', 'a+'))
 6 
 7 r = json.load(open('db', 'r'))
 8 print(r, type(r))
 9 
10 # 輸出:
11 {'tom': 2333, 'whisky': 666, 'peter': 'ok'} <class 'dict'>
load、dump

 

pickle:存儲讀取複雜數據類型(函數、對象)

 1 #處理複雜數據類型(函數等)的方法:pickle(只支持python,不支持Java(支持json))
 2 import pickle
 3 
 4 def sayhi(name):
 5     print('hello,', name)
 6 info = {
 7     'name': 'whitesky',
 8     'age': 25,
 9     'func': sayhi
10 }
11 
12 f = open('test.txt', 'wb')   #pickle序列化要帶b
13 f.write(pickle.dumps(info))  #至關於 pickle._dump(info,f)
14 
15 
16 #pickle反序列化
17 
18 f = open('test.txt', 'rb')
19 data = pickle.loads(f.read()) # 至關於 pickle.load(f)
20 
21 print(data['func'])
22 
23 
24 f.close()
25 
26 
27 #注意:寫程序序列化時要記住只dump一次,只load一次(py3中dump屢次,再load時會出錯,py2中正常),若是須要存儲多個狀態,就dump成多個文件
View Code

 

 1 # -*- coding: utf-8 -*-
 2 
 3 
 4 import pickle
 5 
 6 test = [1, 2]
 7 
 8 
 9 def change(inner_list=[]):
10     inner_list += [2, 3]
11 
12 change(test)
13 
14 pickle.dump(test, open('test_pickle_file', 'wb'))
15 print(pickle.load(open('test_pickle_file', 'rb')))
16 
17 # 輸出 [1, 2, 2, 3]

 

 

XML

格式以下:

 1 <data>
 2     <country name="Liechtenstein">
 3         <rank updated="yes">2</rank>
 4         <year>2023</year>
 5         <gdppc>141100</gdppc>
 6         <neighbor direction="E" name="Austria" />
 7         <neighbor direction="W" name="Switzerland" />
 8     </country>
 9     <country name="Singapore">
10         <rank updated="yes">5</rank>
11         <year>2026</year>
12         <gdppc>59900</gdppc>
13         <neighbor direction="N" name="Malaysia" />
14     </country>
15     <country name="Panama">
16         <rank updated="yes">69</rank>
17         <year>2026</year>
18         <gdppc>13600</gdppc>
19         <neighbor direction="W" name="Costa Rica" />
20         <neighbor direction="E" name="Colombia" />
21     </country>
22 </data>

一、解析XML

 1 from xml.etree import ElementTree as ET
 2 
 3 #打開文件,讀取XML內容
 4 str_xml = open('first.xml', 'r').read()
 5 
 6 #將字符串解析成xml特殊對象,root代指xml文件的根節點
 7 root = ET.XML(str_xml)
 8 
 9 #
10 root1 = ET.XML(open('first.xml', 'r', encoding='utf-8').read())
利用ElementTree.XML將字符串解析成xml對象
1 from xml.etree import ElementTree as ET
2 
3 # 直接解析xml文件
4 tree = ET.parse('first.xml')
5 
6 # 獲取xml文件的根節點
7 root = tree.getroot()
利用ElementTree.parse將文件直接解析成xml對象

 

1 xml自閉標籤:http://www.cnblogs.com/ckysea/p/4627423.html 一個XML標籤就是一個XML元素。 一個XML標籤分爲開始標籤和結束標籤,在開始標籤和結束標籤之間的文本被稱爲標籤體。 包含標籤體:<a>www.itcast.cn</a>;                  若是一個不包含標籤體也不包含其餘元素,那麼能夠將開始標籤和結束標籤合併,這樣的標籤稱爲自閉標籤 不含標籤體及其餘元素:<a></a>能夠簡寫爲自閉標籤:<a/>
2 小結:
3 tree:
4 1.由ELementTree建立 ElementTree(xxx)
5 2.getroot() 獲取xml根節點
6 3. write()內存中的xml寫入文件中

 

二、操做XML

a. 遍歷XML文檔的全部內容,遍歷XML中指定的節點

 1 from xml.etree import ElementTree as ET
 2 
 3 # a.遍歷XML文檔的全部內容
 4 '''
 5 ############ 解析方式一:ElementTree.XML ############
 6 str_xml = open('first.xml', 'r').read()
 7 root = ET.XML(str_xml)
 8 '''
 9 ############ 解析方式二:ElementTree.parse ############
10 tree = ET.parse('first.xml')
11 root = tree.getroot()
12 
13 # print(root.tag)  # 頂層標籤
14 
15 for second_tag in root:
16     print(second_tag.tag, second_tag.attrib)
17     for third_tag in second_tag:
18         print(third_tag.tag, third_tag.text)
19 
20 
21 # b.遍歷XML中指定的節點
22 # 遍歷XML中全部的year節點
23 for node in root.iter('year'):
24     print(node.attrib, node.text)
View Code

 b.修改節點內容

因爲修改的節點時,均是在內存中進行,其不會影響文件中的內容。因此,若是想要修改,則須要從新將內存中的內容寫到文件。
 1 ######## 解析方式一:ElementTree.XML ########
 2 str_xml = open('first.xml', 'r').read()
 3 root = ET.XML(str_xml)
 4 print(root.tag)  # 頂層標籤
 5 # 循環全部的year節點
 6 for node in root.iter('year'):
 7     new_year = int(node.text) + 1
 8     node.text = str(new_year)
 9 # 設置屬性
10     node.set('name', 'alex')
11     node.set('age', '18')
12 # 刪除屬性
13     del node.attrib['name']
14 
15 ############ 保存文件 ############
16 tree = ET.ElementTree(root)
17 tree.write("newnew.xml", encoding='utf-8')
18 
19 ##### 解析方式二:ElementTree.parse #####
20 tree = ET.parse('first.xml')
21 root = tree.getroot()
22 # 修改節點方法同方式一
23 # 保存文件方式和一有區別
24 tree.write("newnew.xml", encoding='utf-8')
兩種方式修改、保存節點的內容

tree做用總結:

1 xml自閉標籤:http://www.cnblogs.com/ckysea/p/4627423.html 一個XML標籤就是一個XML元素。 一個XML標籤分爲開始標籤和結束標籤,在開始標籤和結束標籤之間的文本被稱爲標籤體。 包含標籤體:<a>www.itcast.cn</a>;                  若是一個不包含標籤體也不包含其餘元素,那麼能夠將開始標籤和結束標籤合併,這樣的標籤稱爲自閉標籤 不含標籤體及其餘元素:<a></a>能夠簡寫爲自閉標籤:<a/>
2 小結:
3 tree的做用:
4 1.由ELementTree建立 ElementTree(root根節點)
5 2.getroot方法,獲取xml根節點
6 3. write()內存中的xml寫入文件中,要保存xml字符串必需要有tree
View Code

 建立tree的方式:

1 建立tree的兩種方式:
2 tree = ET.parse('文件名')
3 tree = ET.ElementTree(根節點(Element對象))

 

c.刪除節點(remove方法只能刪除子節點,因此remove前要先找到父節點,經過父節點刪除子節點)

 1 from xml.etree import ElementTree as ET
 2 ############ 解析字符串方式打開 ############
 3 str_xml = open('first.xml', 'r').read()
 4 root = ET.XML(str_xml) # root代指xml文件的根節點data
 5 
 6 print(root.tag)
 7 # 遍歷data下的全部country節點
 8 for node in root.findall('country'):  # findall/find不能跨節點查找,只能從最外層逐層查找
 9     for s in node.findall('year'):
10         node.remove(s)
11 
12 tree = ET.ElementTree(root)
13 tree.write("newnew.xml", encoding='utf-8')
解析字符串方式打開
 1 from xml.etree import ElementTree as ET
 2 tree = ET.parse('first.xml')
 3 root = tree.getroot()
 4 
 5 for country in root.findall('country'):
 6     for s in country.findall('rank'):
 7         rank = int(country.find('rank').text)
 8         if rank > 50:
 9             country.remove(s)  # rank節點大於50的刪除
10 
11 tree.write("newnew.xml", encoding='utf-8')
解析文件方式

 

三、建立XML文檔

 1 # 建立XML文檔
 2 from xml.etree import ElementTree as ET
 3 # 建立根節點
 4 root = ET.Element('family')
 5 
 6 # 建立節點老大
 7 son1 = root.makeelement('son', {'name': '老大'})
 8 #
 9 # son1 = ET.Element('son', {'name': '兒1'})
10 
11 #建立老二
12 son2 = root.makeelement('son', {'name': '老二'})
13 #
14 # son2 = ET.Element('son', {"name": '兒2'})
15 
16 #在老大中建立兩個孫子節點
17 grandson1 = ET.Element('grandson', {'name': '兒11'})
18 grandson2 = ET.Element('grandson', {'name': '兒22'})
19 #
20 # grandson1 = son1.makeelement('grandson', {'name': '兒11'})
21 # grandson2 = son1.makeelement('grandson', {'name': '兒12'})
22 son1.append(grandson1)
23 son1.append(grandson2)
24 
25 #添加老大到根節點
26 root.append(son1)
27 root.append(son2)
28 
29 tree = ET.ElementTree(root)
30 tree.write('0815.xml',encoding='utf-8')
建立方式一
 1 from xml.etree import ElementTree as ET
 2 
 3 
 4 # 建立根節點
 5 root = ET.Element("famliy")
 6 
 7 
 8 # 建立節點大兒子
 9 son1 = ET.SubElement(root, "son", attrib={'name': '兒1'})
10 # 建立小兒子
11 son2 = ET.SubElement(root, "son", attrib={"name": "兒2"})
12 
13 # 在大兒子中建立一個孫子
14 grandson1 = ET.SubElement(son1, "age", attrib={'name': '兒11'})
15 grandson1.text = '孫子'
16 
17 
18 et = ET.ElementTree(root)  #生成文檔對象
19 et.write("test.xml", encoding="utf-8", xml_declaration=True, short_empty_elements=False)
20 
21 建立方式(三)
方式二
1 <family>
2     <son name="老大">
3         <grandson name="兒11" />
4         <grandson name="兒22" />
5     </son>
6     <son name="老二" />
7 </family>
建立好的XML

 XML設置縮進

 1 from xml.etree import ElementTree as ET
 2 from xml.dom import minidom
 3 
 4 
 5 def prettify(elem):
 6     """將節點轉換成字符串,並添加縮進。
 7     """
 8     rough_string = ET.tostring(elem, 'utf-8')
 9     reparsed = minidom.parseString(rough_string)
10     return reparsed.toprettyxml(indent="\t")
11 
12 # 建立根節點
13 root = ET.Element("famliy")
14 
15 
16 # 建立大兒子
17 # son1 = ET.Element('son', {'name': '兒1'})
18 son1 = root.makeelement('son', {'name': '兒1'})
19 # 建立小兒子
20 # son2 = ET.Element('son', {"name": '兒2'})
21 son2 = root.makeelement('son', {"name": '兒2'})
22 
23 # 在大兒子中建立兩個孫子
24 # grandson1 = ET.Element('grandson', {'name': '兒11'})
25 grandson1 = son1.makeelement('grandson', {'name': '兒11'})
26 # grandson2 = ET.Element('grandson', {'name': '兒12'})
27 grandson2 = son1.makeelement('grandson', {'name': '兒12'})
28 
29 son1.append(grandson1)
30 son1.append(grandson2)
31 
32 
33 # 把兒子添加到根節點中
34 root.append(son1)
35 root.append(son1)
36 
37 
38 raw_str = prettify(root)
39 
40 f = open("xxxoo.xml",'w',encoding='utf-8')
41 f.write(raw_str)
42 f.close()
View Code

 

 

configparser

configparser用於處理特定格式的文件,其本質上是利用open來操做文件。(ini配置文件例子)

[section1] # 節點
k1 = v1    #
k2:v2       #

[section2] # 節點
k1 = v1    #

[test_ansible]
node1 = 192.168.2.3
ansible_ssh_port = 22
ansible_ssh_user = gxy_ansible
ansible_su_pass = 123456
漢字 = 123
 1 import configparser
 2 
 3 # 獲取全部節點的值
 4 config = configparser.ConfigParser()
 5 config.read('ini', encoding='utf-8') # 讀到內存當中
 6 ret = config.sections()             # 獲取全部節點的值
 7 print(ret)
 8 # 輸出:['section1', 'section2', 'test_ansible']
 9 
10 
11 # 獲取指定節點下全部的鍵值對
12 config = configparser.ConfigParser()
13 config.read('ini', encoding='utf-8')
14 ret = config.items('test_ansible')   # 獲取指定節點下全部的鍵值對
15 print(ret)
16 # 輸出[('node1', '192.168.2.3'), ('ansible_ssh_port', '22'), ('ansible_ssh_user', 'gxy_ansible'), ('ansible_su_pass', '123456'), ('漢字', '123')]
17 
18 
19 # 獲取指定節點下全部的鍵
20 config = configparser.ConfigParser()
21 config.read('ini',encoding='utf-8')
22 ret = config.options('test_ansible')  # 獲取指定節點下全部的鍵
23 print(ret)
24 # 輸出:['node1', 'ansible_ssh_port', 'ansible_ssh_user', 'ansible_su_pass', '漢字']
25 
26 
27 # 獲取指定節點下指定key的值
28 config = configparser.ConfigParser()
29 config.read('ini', encoding='utf-8')
30 value = config.get('test_ansible', 'node1')  # 獲取指定節點下指定key的值
31 # v = config.getint('test_ansible', 'ansible_su_pass')   # 字符串轉換爲整形
32 # v1 = config.getfloat('test_ansible', 'ansible_su_pass')
33 # v2 = config.getboolean('test_ansible', 'node1')
34 print(value)
35 # 輸出: 192.168.2.3
36 
37 
38 # 檢查、刪除、添加節點
39 config = configparser.ConfigParser()
40 config.read('ini', encoding='utf-8')
41 # 檢查
42 has_sec = config.has_section('test_ansible')
43 print(has_sec)  # 輸出: True
44 # 添加節點
45 config.add_section('test_ansible_new')
46 config.write(open('new_ini', 'w', encoding='utf-8'))
47 # 刪除節點
48 config.remove_section('section2')
49 config.write(open('new_ini', 'w', encoding='utf-8'))
50 
51 
52 # 檢查、刪除、設置指定組內的鍵值對
53 config = configparser.ConfigParser()
54 config.read('ini', encoding='utf-8')
55 
56 has_opt = config.has_option('test_ansible', '漢字')  # 檢查,('鍵','值')
57 print(has_opt)
58 
59 config.remove_option('section1', 'k1')
60 config.write(open('delete_ini', 'w', encoding='utf-8'))
61 
62 config.set('section1', 'k2', '666666')    # 設置, 有則改,沒有則新增
63 config.write(open('set_ini', 'w', encoding='utf-8'))

 

 

logging模塊(用於便捷記錄日誌且線程安全的模塊):

單文件日誌

 1 import logging
 2   
 3   
 4 logging.basicConfig(filename='log.log',
 5                     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
 6                     datefmt='%Y-%m-%d %H:%M:%S %p',
 7                     level=10)
 8   
 9 logging.debug('debug')
10 logging.info('info')
11 logging.warning('warning')
12 logging.error('error')
13 logging.critical('critical')
14 logging.log(10,'log')

 

日誌等級:

1 CRITICAL = 50
2 FATAL = CRITICAL
3 ERROR = 40
4 WARNING = 30
5 WARN = WARNING
6 INFO = 20
7 DEBUG = 10
8 NOTSET = 0
View Code

注:只有【當前寫等級level】大於【日誌等級】時,日誌文件才被記錄。

 

 

多文件日誌

對於上述記錄日誌的功能,只能將日誌記錄在單文件中,若是想要設置多個日誌文件,logging.basicConfig將沒法完成,須要自定義文件和日誌操做對象。

 1 # 定義文件
 2 file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')
 3 fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
 4 file_1_1.setFormatter(fmt)
 5 
 6 file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
 7 fmt = logging.Formatter()
 8 file_1_2.setFormatter(fmt)
 9 
10 # 定義日誌
11 logger1 = logging.Logger('s1', level=logging.ERROR)
12 logger1.addHandler(file_1_1)    #兩個日誌文件所有加入logger1文件對象中,則記錄日誌時,會同時寫入兩個文件
13 logger1.addHandler(file_1_2)
14 
15 
16 # 寫日誌
17 logger1.critical('1111')
18 

 

1 # 定義文件
2 file_2_1 = logging.FileHandler('l2_1.log', 'a')
3 fmt = logging.Formatter()
4 file_2_1.setFormatter(fmt)
5 
6 # 定義日誌
7 logger2 = logging.Logger('s2', level=logging.INFO)
8 logger2.addHandler(file_2_1)
日誌(二)

 

如上述建立的兩個日誌對象

  • 當使用【logger1】寫日誌時,會將相應的內容寫入 l1_1.log 和 l1_2.log 文件中
  • 當使用【logger2】寫日誌時,會將相應的內容寫入 l2_1.log 文件中
  1 import logging
  2   
  3 # 日誌配置:
  4 logging.basicConfig(filename='log.log',
  5                     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
  6                     datefmt='%Y-%m-%d %H:%M:%S %p',
  7                     level=10)
  8  
  9 # 日誌記錄的方法: 
 10 logging.debug('debug')        # 內部調用的logging.log, 至關於logging.log(10,'debug')
 11 logging.info('info')
 12 logging.warning('warning')  # 建議用這
 13 logging.error('error')
 14 logging.critical('critical')
 15 logging.log(10,'log')
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 # 定義文件
 24 #建立第一個文件對象(FileHandler方法)
 25 file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')            # 定義文件名爲:l1_1.log
 26 fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")    # logging.Formatter格式化處理
 27 file_1_1.setFormatter(fmt)
 28 
 29 #建立第二個文件對象
 30 file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
 31 fmt = logging.Formatter()
 32 file_1_2.setFormatter(fmt)
 33 
 34 
 35 # 定義日誌
 36 #建立寫日誌的對象
 37 logger1 = logging.Logger('s1', level=logging.ERROR)  # s1會寫到logging.Formatter的%(name)處
 38 logger1.addHandler(file_1_1)                        # 將文件對象加入寫日誌的對象中,用於寫日誌
 39 logger1.addHandler(file_1_2)
 40 
 41 
 42 # 寫日誌
 43 logger1.critical('1111')                    # 關聯了上面兩個文件(file_1_1和file_1_2),因此一條日誌信息會同時寫入上面兩個文件中
 44 
 45 
 46 
 47 
 48 
 49 # 實戰:
 50 同時定義兩個日誌文件,
 51 # 定義文件
 52 file_1_1 = logging.FileHandler('run.log', 'a', encoding='utf-8')    # 定義文件名爲:run.log
 53 fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
 54 file_1_1.setFormatter(fmt)
 55 
 56 # 定義日誌
 57 logger1 = logging.Logger('s1', level=logging.ERROR)
 58 logger1.addHandler(file_1_1)
 59 
 60 # 寫日誌
 61 logger1.critical('1111')
 62 
 63 
 64 
 65 # 定義文件
 66 file_1_1 = logging.FileHandler('error.log', 'a', encoding='utf-8')    # 定義文件名爲:error.log
 67 fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
 68 file_1_1.setFormatter(fmt)
 69 
 70 # 定義日誌
 71 logger1 = logging.Logger('s1', level=logging.ERROR)
 72 logger1.addHandler(file_1_1)
 73 
 74 # 寫日誌
 75 logger1.critical('1111')
 76 
 77 
 78 CMDB中的應用:
 79     def initialize_run_log(self):
 80         self.check_path_exist(self.run_log_file)
 81         file_1_1 = logging.FileHandler(self.run_log_file, 'a', encoding='utf-8')    # 文件對象
 82         fmt = logging.Formatter(fmt="%(asctime)s - %(levelname)s :  %(message)s")    # 設置日誌格式
 83         file_1_1.setFormatter(fmt)                                                    # 設置日誌格式
 84         logger1 = logging.Logger('run_log', level=logging.INFO)
 85         logger1.addHandler(file_1_1)
 86         self.run_logger = logger1
 87 
 88     def initialize_error_log(self):
 89         self.check_path_exist(self.error_log_file)
 90         file_1_1 = logging.FileHandler(self.error_log_file, 'a', encoding='utf-8')
 91         fmt = logging.Formatter(fmt="%(asctime)s  - %(levelname)s :  %(message)s")
 92         file_1_1.setFormatter(fmt)
 93         logger1 = logging.Logger('run_log', level=logging.ERROR)
 94         logger1.addHandler(file_1_1)
 95         self.error_logger = logger1
 96         
 97     def log(self, message, mode=True):
 98         """
 99         寫入日誌
100         :param message: 日誌信息
101         :param mode: True表示運行信息,False表示錯誤信息
102         :return:
103         """
104         if mode:
105             self.run_logger.info(message)
106         else:
107             self.error_logger.error(message)
logging方法實踐

 https://www.cnblogs.com/liujiacai/p/7804848.html

 

 

http://python.jobbole.com/81666/      

https://www.jianshu.com/p/d615bf01e37b     多進程日誌 

https://www.cnblogs.com/bethansy/p/7716747.html

 

traceback捕獲並打印異常:

 1 異常處理是平常操做了,可是有時候不能只能打印咱們處理的結果,還須要將咱們的異常打印出來,這樣更直觀的顯示錯誤
 2 下面來介紹traceback模塊來進行處理
 3     try:
 4         1/0
 5     except Exception, e:
 6         print e
 7 輸出結果是integer division or modulo by zero,只知道是報了這個錯,可是殊不知道在哪一個文件哪一個函數哪一行報的錯。
 8 
 9 使用traceback
10     try:
11         1/0
12     except Exception, e:
13         traceback.print_exc()
14 Traceback (most recent call last):
15 
16         File "test_traceback.py", line 3, in <module>
17 
18            1/0
19 
20 ZeroDivisionError: integer division or modulo by zero  # 這樣很是直觀有利於調試。
21 
22 # traceback.print_exc()跟traceback.format_exc()有什麼區別呢?
23 print_exc()則直接給打印出來;
24 format_exc()返回字符串;
25 即traceback.print_exc()與print traceback.format_exc()效果是同樣的。
26 print_exc()還能夠接受file參數直接寫入到一個文件。
27 好比:
28 traceback.print_exc(file=open('tb.txt','w+')) # 寫入到tb.txt文件去。        

 

 1 也可使用logger.exception(msg,_args),它等價於logger.error(msg,exc_info = True,_args),
 2 
 3  4 
 5 logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)
 6 替換爲,
 7 
 8 logger.exception("Failed to open sklearn.txt from logger.exception")
 9 控制檯和日誌文件log.txt中輸出,
10 
11 Start print log
12 Something maybe fail.
13 Failed to open sklearn.txt from logger.exception
14 Traceback (most recent call last):
15   File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in <module>
16     open("sklearn.txt","rb")
17 IOError: [Errno 2] No such file or directory: 'sklearn.txt'
18 Finish

 

 

1 import和__import__()有什麼不一樣?
2 
3 import做用:
4 導入/引入一個python標準模塊,其中包括.py文件、帶有__init__.py文件的目錄;
5 
6 __import__做用:
7 同import語句一樣的功能,但__import__是一個函數,而且只接收字符串做爲參數,因此它的做用就可想而知了。其實import語句就是調用這個函數進行導入工做的,import sys <==>sys = __import__('sys')。
import和__import__()
 1 s.rsplit()和s.split()區別是什麼啊
 2 
 3 一個從左開始,一個從右開始。
 4 若是是這樣沒有區別:
 5 >>> s = 'asd dfdf ff'
 6 >>> s.split()
 7 ['asd', 'dfdf', 'ff']
 8 >>> s.rsplit()
 9 ['asd', 'dfdf', 'ff']
10 
11 這樣就看出不一樣了。
12 >>> s.split(' ',1)
13 ['asd', 'dfdf ff']
14 >>> s.rsplit(' ',1)
15 ['asd dfdf', 'ff']
s.rsplit()和s.split()區別是什麼啊

 

random模塊:

 1 # random 模塊
 2 import random
 3 
 4 print(random.random())
 5 print(random.randint(1, 2))     # Return random integer in range [a, b], including both end points.
 6 print(random.randrange(1, 10))  # Choose a random item from range(start, stop[, step]) 不包括stop邊界
 7 
 8 
 9 # 生成隨機驗證碼
10 import random
11 verification_code = ''
12 for i in range(6):
13     rand = random.randrange(0, 4)
14     if rand == 3 or rand == 1:
15         num = random.randint(0, 9)
16         verification_code += str(num)
17     else:
18         num = random.randint(65, 91)
19         letter = chr(num)
20         verification_code += letter
21 print(verification_code)
22 
23 import random
24 verification_code = ''
25 for i in range(6):
26     rand = random.randrange(0, 6)
27     if i == rand:
28         num = random.randint(0, 9)
29         verification_code += str(num)
30     else:
31         num = random.randint(65, 91)
32         letter = chr(num)
33         verification_code += letter
34 print(verification_code)

 

 

importlib

#環境:python 3.6


# 文件結構

├── clazz
│   ├── __init__.py
│   ├── a.py
│   └── b.py
└── main.py



# a.py 的代碼

def show():
    print("show A")
    
    
# b.py 的代碼

def show():
    print("show B")    
    
    
    
從main中導入clazz包中的a 和b 模塊
main.py

import importlib

# 絕對導入
a = importlib.import_module("clazz.a")
a.show()
# show A

# 相對導入
b = importlib.import_module(".b", "clazz")
b.show()
# show B

注意,相對導入有個一點., 相似路徑

 

 

 

unix時間戳:
# 10位時間戳獲取方法:

>>> import time
>>> t = time.time()
>>> print t
1436428326.76
>>> print int(t)
1436428326
>>>


# 13位時間戳獲取方法:
1)默認狀況下python的時間戳是以秒爲單位輸出的float

>>> import time
>>> time.time()
1436428275.207596


# 經過把秒轉換毫秒的方法得到13位的時間戳:
import time
millis = int(round(time.time() * 1000))      # round()四捨五入函數。
print millis




import time
 
current_milli_time = lambda: int(round(time.time() * 1000))
Then:
>>> current_milli_time()
1378761833768
#!/usr/bin/env python3
# -*-coding:utf-8 -*-
# xiaoe直播監控腳本
__author__ = 'budyu'
__date__ = '2019/4/4 21:34'

import requests
import json
import sys
import logging
import datetime

# logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',datefmt='%Y-%m-%d %H:%M:%S %p',level=10)

# file_handler = logging.FileHandler('/var/log/alive_mon.log', 'a', encoding='utf-8')
# fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
# file_handler.setFormatter(fmt)

# logger1 = logging.Logger('alive_mon_log', level=logging.DEBUG)
# logger1.addHandler(file_handler)

start_time = ''
stop_time = ''

now = datetime.datetime.now()
one_min_delta = now - datetime.timedelta(minutes=1)
# now_time = one_min_delta.strftime('%Y-%m-%d %H:%M:%S')
now_time_minute = one_min_delta.strftime('%M')
result = int(now_time_minute) % 5
# print(result)
# print(not result)
#  取0,5,10,15,20...分鐘
if not result:
    stop_time = one_min_delta.strftime('%Y-%m-%d %H:%M:%S')
    stop_time = datetime.datetime.strptime(stop_time, "%Y-%m-%d %H:%M:%S")
    # print(stop_time, '----------------------------')
else:
    stop_time_min = int(now_time_minute) - result
    stop_time = one_min_delta.strftime('%Y-%m-%d %H:{}:%S').format(str(stop_time_min).zfill(2))
    stop_time = datetime.datetime.strptime(stop_time, "%Y-%m-%d %H:%M:%S")
    # print(stop_time, '||||||||||||||||||||||||||||')

start_time = stop_time - datetime.timedelta(minutes=5)
# print(start_time, 'start_time @@@@@@@@@@@@@@@@@@@@@@')

alive_panel_url = 'http://134.175.37.247:1224/alive_panel'
online_user_url = 'http://134.175.37.247:1224/alive_online_users'

payload = {'start_at': start_time, 'stop_at': stop_time}
# payload = {'start_at': '2019-04-10 17:0:20', 'stop_at': '2019-04-10 17:0:00'}
# print(payload)
panel_ret = requests.get(
    url=alive_panel_url,
    # params=payload
)
online_user_ret = requests.get(
    url=online_user_url,
    params=payload
)

# print(panel_ret.text, 'panel_ret -----------')
# print(online_user_ret.text, ' online_user_ret  ----------------')

response_panel = json.loads(panel_ret.text)
response_online_user = json.loads(online_user_ret.text)
# print(response_panel, '======================')
# print(response_online_user, '======================')

if response_panel['code'] == 0:
    try:
        if sys.argv[1] == 'avgInterTime':
            avgInterTime = response_panel.get('data')['avgInterTime']
            print(int(avgInterTime))
        elif sys.argv[1] == 'interFailRate':
            interFailRate = response_panel.get('data')['interFailRate']
            print(interFailRate)
        elif sys.argv[1] == 'interReqCount':
            interReqCount = response_panel.get('data')['interReqCount']
            print(int(interReqCount))
        elif response_online_user['code'] == 0 and sys.argv[1] == 'onlineUsers':
            onlineUsers = response_online_user.get('data')['onlineUsers']
            print(int(onlineUsers))
        else:
            print(
                "response_online_user failed! (Usage: python {0} avgInterTime|interFailRate|interReqCount|onlineUsers)".format(
                    sys.argv[0]))
    except Exception as e:
        #    logger1.critical('may be get wrong argument !')
        print("reponse error! INFO:{0}".format(e))

elif response_panel['code'] == 12:
    # logger1.critical('no data repsonse from {0}'.format(requests_url))
    print('no data')
elif response_panel['code'] == 8:
    # logger1.critical('request timeout from {0}'.format(requests_url))
    print('request time error')

 

常用的時間方法


1.獲得當前時間
使用time模塊,首先獲得當前的時間戳
In [42]: time.time()
Out[42]: 1408066927.208922

將時間戳轉換爲時間元組 struct_time
In [43]: time.localtime(time.time())
Out[43]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=9, tm_min=42, tm_sec=20, tm_wday=4, tm_yday=227, tm_isdst=0)

格式化輸出想要的時間
In [44]: time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
Out[44]: '2014-08-15 09:43:04'

接上文,不加參數時,默認就是輸出當前的時間
In [48]: time.strftime('%Y-%m-%d %H:%M:%S')
Out[48]: '2014-08-15 09:46:53’

固然也能夠透過datetime模塊來實現,以下:
In [68]: t = time.time()
In [69]: datetime.datetime.fromtimestamp(t).strftime('%Y-%m-%d %H:%M:%S')
Out[69]: '2014-08-15 10:04:51’

同時,也能夠只使用datetime模塊
In [46]: datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
Out[46]: '2014-08-15 09:45:27’
In [47]: datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S')
Out[47]: '2014-08-15 09:46:10'

2.獲取時間差,計算程序的執行時間等:
使用time模塊:
In [75]: def t():
   ....:     start = time.time()
   ....:     time.sleep(10)
   ....:     end = time.time()
   ....:     print end - start
   ....:

In [76]: t()
10.0014948845

使用datetime模塊:
In [49]: starttime = datetime.datetime.now()
In [50]: endtime = datetime.datetime.now()
In [51]: print (endtime - starttime).seconds


2.計算昨天的日期(發散思惟,計算其餘日期相加、相減等):

In [52]: d1 = datetime.datetime.now()
In [53]: d2 = d1 - datetime.timedelta(days=1)
In [54]: d1
Out[54]: datetime.datetime(2014, 8, 15, 9, 54, 10, 68665)
In [55]: d2
Out[55]: datetime.datetime(2014, 8, 14, 9, 54, 10, 68665)



3.時間元組 struct_time轉化爲時間戳
In [56]: datetime.datetime.now()
Out[56]: datetime.datetime(2014, 8, 15, 9, 57, 52, 779893)

In [57]: datetime.datetime.now().timetuple()
Out[57]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=9, tm_min=58, tm_sec=12, tm_wday=4, tm_yday=227, tm_isdst=-1)

In [58]: time.mktime(datetime.datetime.now().timetuple())
Out[58]: 1408067904.0



4.strptime也挺有用的,將時間字符串轉換爲時間元組struct_time
In [73]: time.strftime('%Y-%m-%d %H:%M:%S')
Out[73]: '2014-08-15 10:27:36'

In [74]: time.strptime('2014-08-15 10:27:36','%Y-%m-%d %H:%M:%S')
Out[74]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=10, tm_min=27, tm_sec=36, tm_wday=4, tm_yday=227, tm_isdst=-1)






二:time和datetime模塊經常使用方法簡介

表示時間的兩種方式:

1. 時間戳(相對於1970.1.1 00:00:00以秒計算的偏移量),時間戳是唯一的
2. 時間元組 即(struct_time),共有九個元素,分別表示,同一個時間戳的struct_time會由於時區不一樣而不一樣


time 模塊經常使用方法小記:
1.time.clock()

這個須要注意,在不一樣的系統上含義不一樣。在UNIX系統上,它返回的是「進程時間」,它是用秒錶示的浮點數(時間 戳)。而在WINDOWS中,第一次調用,返回的是進程運行的實際時間。而第二次以後的調用是自第一次調用之後到如今的運行時間。(其實是以WIN32 上QueryPerformanceCounter()爲基礎,它比毫秒錶示更爲精確)

budong@budongdeMacBook-Pro:/tmp$ cat clock.py
#!/usr/bin/env python
import time
if __name__ == '__main__':
    time.sleep(1)
    print "clock1:%s" % time.clock()
    time.sleep(1)
    print "clock2:%s" % time.clock()
    time.sleep(1)
    print "clock3:%s" % time.clock()

運行腳本:
budong@budongdeMacBook-Pro:/tmp$ ./clock.py
clock1:0.059173
clock2:0.059299
clock3:0.059416



2.time.sleep(secs)

線程推遲指定的時間運行
適合放在腳本里,定時sleep一會而後繼續幹啥

In [138]: while True:
   .....:     time.sleep(3)
   .....:     print time.strftime('%H:%M:%S')
   .....:
17:21:35
17:21:38
17:21:41
17:21:44
……



3.time.localtime([secs])

將一個時間戳轉換成一個當前時區的struct_time,若是seconds參數未輸入,則以當前時間爲轉換標準
未提供secs參數時,按當前時間爲準
In [141]: time.localtime()
Out[141]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=14, tm_hour=17, tm_min=23, tm_sec=48, tm_wday=3, tm_yday=226, tm_isdst=0)

提供secs爲當前時間戳時
In [142]: time.time()
Out[142]: 1408008232.217969
In [143]: time.localtime(time.time())
Out[143]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=14, tm_hour=17, tm_min=24, tm_sec=2, tm_wday=3, tm_yday=226, tm_isdst=0)



4.time.strftime(format[, t])

將指定的struct_time(默認爲當前時間),根據指定的格式化字符串輸出
t未指定,傳入time.localtime()做爲默認參數:
In [156]: time.strftime('%Y-%m-%d %H:%M:%S')
Out[156]: '2014-08-14 17:28:16’

指定t爲time.localtime(1407945600.0)時:
In [157]: time.localtime(1407945600.0)
Out[157]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=14, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=226, tm_isdst=0)

In [158]: time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(1407945600.0))
Out[158]: '2014-08-14 00:00:00’


5.time.time()

返回當前時間的時間戳
In [161]: time.time()
Out[161]: 1408008711.730218


6.time.mktime(t)

將一個struct_time轉換爲時間戳,以下time.localtime接收一個時間戳返回一個struct_time,而time.mktime接收一個struct_time,返回一個時間戳
In [159]: time.localtime(1407945600.0)
Out[159]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=14, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=226, tm_isdst=0)
In [160]: time.mktime(time.localtime(1407945600.0))
Out[160]: 1407945600.0

殘陽似血的博客:<http://qinxuye.me/article/details-about-time-module-in-python/> 

官方time模塊:<http://python.me/library/time.html#module-time>



##datetime 模塊經常使用方法小記

datetime模塊經常使用的主要有下面這四個類:

1. datetime.date: 是指年月日構成的日期(至關於日曆)
2. datetime.time: 是指時分秒微秒構成的一天24小時中的具體時間(至關於手錶)
3. datetime.datetime: 上面兩個合在一塊兒,既包含時間又包含日期
4. datetime.timedelta: 時間間隔對象(timedelta)。一個時間點(datetime)加上一個時間間隔(timedelta)能夠獲得一個新的時間點(datetime)。好比今天的上午3點加上5個小時獲得今天的上午8點。同理,兩個時間點相減會獲得一個時間間隔。


1.datetime.date 類

1.新建一個date對象,日期爲今天,既能夠直接調用datetime.date.today(),也能夠直接向datetime.date()傳值,以下:
In [4]: today = datetime.date.today()
In [5]: today
Out[5]: datetime.date(2014, 8, 15)
In [6]: t = datetime.date(2014,8,15)
In [7]: t
Out[7]: datetime.date(2014, 8, 15)

2.datetime.date.strftime(format) 格式化爲須要的時間,如經常使用的 「年-月-日 小時:分鐘:秒」 格式
In [8]: today.strftime('%Y-%m-%d %H:%M:%S')
Out[8]: '2014-08-15 00:00:00’
date對象中小時、分鐘、秒默認都是0,紀元年的那個時間

3.datetime.date.timple() 轉成struct_time格式,這樣傳遞給time.mktime(t)  後,直接轉成時間戳格式
In [9]: today.timetuple()
Out[9]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=227, tm_isdst=-1)
In [10]: time.mktime(today.timetuple())
Out[10]: 1408032000.0

4.datetime.date.replace(year, month, day)  返回一個替換後的date對象
In [11]: today.replace(year=2013)
Out[11]: datetime.date(2013, 8, 15)

5.datetime.date.fromtimestamp(timestamp) 將時間戳轉化爲date對象
In [12]: datetime.date.fromtimestamp(1408058729)
Out[12]: datetime.date(2014, 8, 15)



2.datetime.time 類

1.新建一個time對象
In [15]: t
Out[15]: datetime.time(8, 45, 20)

2.datetime.time.(format)格式化輸出
In [16]: t.strftime('%Y-%m-%d %H:%M:%S')
Out[16]: '1900-01-01 08:45:20’
time對應的年、月、日爲1900、0一、01,紀元年的那個時間

3.datetime.time.replace([hour[, minute[, second[, microsecond[, tzinfo]]]]])  返回一個替換後的time對象
In [17]: t.replace(hour=9)
Out[17]: datetime.time(9, 45, 20)


3.datetime.datetime類

其實和date的那些方法差很少了,大概看如下,簡單說說
1.新建一個datetime對象,日期爲今天,既能夠直接調用datetime.datetime.today(),也能夠直接向datetime.datetime()傳值,以下:
In [21]: d1 = datetime.datetime.today()
In [22]: d1
Out[22]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
In [23]: d2 = datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
In [24]: d2
Out[24]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)

2.datetime.datetime.now([tz]) 當不指定時區時,和datetime.datetime.today()是同樣的結果,以下
In [25]: datetime.datetime.now()
Out[25]: datetime.datetime(2014, 8, 15, 8, 14, 50, 738672)

3..datetime.datetime.strftime(format) 格式化爲須要的時間,如經常使用的 「年-月-日 小時:分鐘:秒」 格式
In [27]: d1
Out[27]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
In [28]: d1.strftime('%Y-%m-%d %H:%M:%S')
Out[28]: '2014-08-15 08:12:34’

4.datetime.datetime.timple() 轉成struct_time格式,這樣傳遞給time.mktime(t)  後,直接轉成時間戳格式
In [29]: d1
Out[29]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
In [30]: d1.timetuple()
Out[30]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=8, tm_min=12, tm_sec=34, tm_wday=4, tm_yday=227, tm_isdst=-1)
In [31]: time.mktime(d1.timetuple())
Out[31]: 1408061554.0

5.datetime.datetime.replace(year, month, day)  返回一個替換後的date對象
In [32]: d1
Out[32]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
In [33]: d1.replace(year=2000)
Out[33]: datetime.datetime(2000, 8, 15, 8, 12, 34, 790945)

6.datetime.datetime.fromtimestamp(timestamp) 將時間戳轉化爲datetime對象
In [34]: time.time()
Out[34]: 1408061894.081552
In [35]: datetime.datetime.fromtimestamp(1408061894)
Out[35]: datetime.datetime(2014, 8, 15, 8, 18, 14)


4.datetime.timedelta類
主要作時間的加減法用,以下:
In [78]: today = datetime.datetime.today()
In [79]: yesterday = today - datetime.timedelta(days=1)
In [80]: yesterday
Out[80]: datetime.datetime(2014, 8, 14, 15, 8, 25, 783471)
In [81]: today
Out[81]: datetime.datetime(2014, 8, 15, 15, 8, 25, 783471)


當前時間

datetime.datetime.now() 
 

時間間隔

datetime.timedelta(參數=數值)  #參數:weeks,days,hours,minutes,seconds,microseconds,milliseconds


import datetime

nowtime = datetime.datetime.now()
print(nowtime) #當前時間

print(datetime.datetime.now() - datetime.timedelta(days=1)) #1天前 默認格式2019-02-11 13:27:16.231381
print(datetime.datetime.now() + datetime.timedelta(days=1)) #1天后

print((datetime.datetime.now() - datetime.timedelta(weeks=2)).strftime("%Y-%m-%d %H:%M:%S")) #兩週前
print((datetime.datetime.now() + datetime.timedelta(weeks=2)).strftime("%Y-%m-%d %H:%M:%S")) #兩週後

print((datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S")) #1天前
print((datetime.datetime.now() + datetime.timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S"))#1天后

print((datetime.datetime.now() - datetime.timedelta(hours=2)).strftime("%Y-%m-%d %H:%M:%S")) #2小時前
print((datetime.datetime.now() + datetime.timedelta(hours=2)).strftime("%Y-%m-%d %H:%M:%S")) #2小時後

print((datetime.datetime.now() - datetime.timedelta(minutes=30)).strftime("%Y-%m-%d %H:%M:%S"))# 30分鐘前
print((datetime.datetime.now() + datetime.timedelta(minutes=30)).strftime("%Y-%m-%d %H:%M:%S")) #30分鐘後

print((datetime.datetime.now() - datetime.timedelta(seconds=10)).strftime("%Y-%m-%d %H:%M:%S")) #10秒前
print((datetime.datetime.now() + datetime.timedelta(seconds=10)).strftime("%Y-%m-%d %H:%M:%S")) #10秒後
經常使用事件方法

 

python datetime time 時間模塊

 https://www.jianshu.com/p/70180a1766a2 

 

日期、時間戳互轉:

# 引入模塊
import time, datetime

# str類型的日期轉換爲時間戳
# 字符類型的時間
tss1 = '2013-10-10 23:40:00'
# 轉爲時間數組
timeArray = time.strptime(tss1, "%Y-%m-%d %H:%M:%S")
print timeArray     
# timeArray能夠調用tm_year等
print timeArray.tm_year   # 2013
# 轉爲時間戳
timeStamp = int(time.mktime(timeArray))
print timeStamp  # 1381419600


# 結果以下
time.struct_time(tm_year=2013, tm_mon=10, tm_mday=10, tm_hour=23, tm_min=40, tm_sec=0, tm_wday=3, tm_yday=283, tm_isdst=-1)
2013
1381419600



# 更改str類型日期的顯示格式
tss2 = "2013-10-10 23:40:00"
# 轉爲數組
timeArray = time.strptime(tss2, "%Y-%m-%d %H:%M:%S")
# 轉爲其它顯示格式
otherStyleTime = time.strftime("%Y/%m/%d %H:%M:%S", timeArray)
print otherStyleTime  # 2013/10/10 23:40:00

tss3 = "2013/10/10 23:40:00"
timeArray = time.strptime(tss3, "%Y/%m/%d %H:%M:%S")
otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
print otherStyleTime  # 2013-10-10 23:40:00


# 時間戳轉換爲指定格式的日期
# 使用time
timeStamp = 1381419600
timeArray = time.localtime(timeStamp)
otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray)
print otherStyleTime   # 2013--10--10 23:40:00
# 使用datetime
timeStamp = 1381419600
dateArray = datetime.datetime.utcfromtimestamp(timeStamp)
otherStyleTime = dateArray.strftime("%Y--%m--%d %H:%M:%S")
print otherStyleTime   # 2013--10--10 15:40:00

# 獲取當前時間而且用指定格式顯示 
# time獲取當前時間戳
now = int(time.time())     # 1533952277
timeArray = time.localtime(now)
print timeArray
otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray)
print otherStyleTime    

# 結果以下
time.struct_time(tm_year=2018, tm_mon=8, tm_mday=11, tm_hour=9, tm_min=51, tm_sec=17, tm_wday=5, tm_yday=223, tm_isdst=0)
2018--08--11 09:51:17


# datetime獲取當前時間,數組格式
now = datetime.datetime.now()
print now
otherStyleTime = now.strftime("%Y--%m--%d %H:%M:%S")
print otherStyleTime  

# 結果以下:
2018-08-11 09:51:17.362986
2018--08--11 09:51:17

 

獲取最近一個月天天的日期:

#coding:utf-8
# from common.contest import *


import datetime
import time
begin_date = (datetime.datetime.now() - datetime.timedelta(days =30)).strftime("%Y-%m-%d")
date_list = []
begin_date = datetime.datetime.strptime(begin_date, "%Y-%m-%d")
end_date = datetime.datetime.strptime(time.strftime('%Y-%m-%d',time.localtime(time.time())), "%Y-%m-%d")
while begin_date <= end_date:
    date_str = begin_date.strftime("%Y-%m-%d")
    date_list.append(date_str)
    begin_date += datetime.timedelta(days=1)


print date_list


C:\Python27\python.exe E:/squid_frame/weibo_pc_spider_local/test.py
['2019-03-18', '2019-03-19', '2019-03-20', '2019-03-21', '2019-03-22', '2019-03-23', '2019-03-24', '2019-03-25', '2019-03-26', '2019-03-27',
 '2019-03-28', '2019-03-29', '2019-03-30', '2019-03-31', '2019-04-01', '2019-04-02', '2019-04-03', '2019-04-04', '2019-04-05', '2019-04-06', 
'2019-04-07', '2019-04-08', '2019-04-09', '2019-04-10', '2019-04-11', '2019-04-12', '2019-04-13', '2019-04-14', '2019-04-15', '2019-04-16', 
'2019-04-17']

Process finished with exit code 0

 

# 時間、字符串互轉
https://www.cnblogs.com/alfred0311/p/7885349.html    


def time_format(time_str):
    """ str -> datetime"""
    if 'T' in time_str:
        if '+08:00' in time_str:
            UTC_FORMAT = "%Y-%m-%dT%H:%M:%S+08:00"
            return datetime.datetime.strptime(time_str, UTC_FORMAT)
        if 'Z' in time_str:
            UTC_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
            return datetime.datetime.strptime(time_str, UTC_FORMAT) + datetime.timedelta(hours=8)
    else:
        UTC_FORMAT = "%Y-%m-%d %H:%M:%S"
        return datetime.datetime.strptime(time_str, UTC_FORMAT)
相關文章
相關標籤/搜索