day 5 模块导入、常用模块os shutil sys commands subprocess hashlib json pickle zipfile traceback random dateti...

os:

 

 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'))

 

 

 

目录遍历:

os.walk(top, topdown=True, οnerrοr=None, followlinks=False)
可以得到一个三元tupple(dirpath, dirnames, filenames),
第一个为起始路径,第二个为起始路径下的文件夹,第三个是起始路径下的文件。
dirpath 是一个string,代表每一个基于top的目录路径,
dirnames 是一个list,包含了dirpath下所有子目录的名字。
filenames 是一个list,包含了非目录文件的名字。
这些名字不包含路径信息,如果需要得到基于top的全路径,需要使用os.path.join(dirpath, name).

例:

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

import os

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+filename

for dir in dirnames:
    #遍历所有目录
    print dir

 

# 获取一个目录下所有文件,不包括空目录
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-1029

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, οnerrοr=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.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>

1、解析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写入文件中

 

2、操作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')
解析文件方式

 

3、创建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、01、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 

转载于:https://www.cnblogs.com/yum777/p/6768739.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值