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
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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========
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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(),可能出现因文件夹中文件被占用而无法删除,解决方法也很简单,先强制删除文件夹,再重新建同名文件夹即可
- import shutil
- shutil.rmtree('要清空的文件夹名')
- os.mkdir('要清空的文件夹名')
产生异常的可能原因: (1) 路径不存在 (2) 路径子目录中有文件或下级子目录(os.rmdir) (3) 没有操作权限或只读
tip2:把一个文件从一个文件夹移动到另一个文件夹,并同时重命名,用shutil:
shutil.move('原文件夹/原文件名','目标文件夹/目标文件名')
重命名文件夹/文件
可对某一文件或文件夹重命名 os.rename(oldfileName, newFilename)
注意:新文件的扩展名不能遗漏,理论上需要保持类型一致;但这也不失为改文件类型的一种方式(相当于直接改文件的扩展名)
复制、移动文件夹/文件 :(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)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#!/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
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
>>> 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: 没有那个文件或目录
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的load,dump:作用,转换之后写到文件中(不常用)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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'>
pickle:存储读取复杂数据类型(函数、对象)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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成多个文件
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
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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())
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 from xml.etree import ElementTree as ET 2 3 # 直接解析xml文件 4 tree = ET.parse('first.xml') 5 6 # 获取xml文件的根节点 7 root = tree.getroot()
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中指定的节点
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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)
b.修改节点内容
由于修改的节点时,均是在内存中进行,其不会影响文件中的内容。所以,如果想要修改,则需要重新将内存中的内容写到文件。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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作用总结:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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
创建tree的方式:
1 创建tree的两种方式: 2 tree = ET.parse('文件名') 3 tree = ET.ElementTree(根节点(Element对象))
c.删除节点(remove方法只能删除子节点,所以remove前要先找到父节点,通过父节点删除子节点)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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')
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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文档
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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')
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 创建方式(三)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <family> 2 <son name="老大"> 3 <grandson name="儿11" /> 4 <grandson name="儿22" /> 5 </son> 6 <son name="老二" /> 7 </family>
XML设置缩进
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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()
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')
日志等级:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 CRITICAL = 50 2 FATAL = CRITICAL 3 ERROR = 40 4 WARNING = 30 5 WARN = WARNING 6 INFO = 20 7 DEBUG = 10 8 NOTSET = 0
注:只有【当前写等级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
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 文件中
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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)
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
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 import和__import__()有什么不同? 2 3 import作用: 4 导入/引入一个python标准模块,其中包括.py文件、带有__init__.py文件的目录; 5 6 __import__作用: 7 同import语句同样的功能,但__import__是一个函数,并且只接收字符串作为参数,所以它的作用就可想而知了。其实import语句就是调用这个函数进行导入工作的,import sys <==>sys = __import__('sys')。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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']
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')
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
经常使用的时间方法 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秒后