pathlib:
pathlib介绍-比os.path更好的路径处理方式:https://zhuanlan.zhihu.com/p/33524938
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下为" ",Linux下为" " 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:UserswPycharmProjectspythonhashlibin') 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/hashlibin 29 C:UserswPycharmProjectspythonhashlib 30 C:UserswPycharmProjects 31 C:UserswAppDataLocalProgramsPythonPython35python35.zip 32 C:UserswAppDataLocalProgramsPythonPython35DLLs 33 C:UserswAppDataLocalProgramsPythonPython35lib 34 C:UserswAppDataLocalProgramsPythonPython35 35 C:UserswAppDataLocalProgramsPythonPython35libsite-packages 36 C:/Users/w/PycharmProjects/python/hashlibin 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, onerror=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, onerror=None, followlinks=False)
Directory tree generator.
For each directory in the directory tree rooted at top (including top
itself, but excluding '.' and '..'), yields a 3-tuple
dirpath, dirnames, filenames
dirpath is a string, the path to the directory. dirnames is a list of
the names of the subdirectories in dirpath (excluding '.' and '..').
filenames is a list of the names of the non-directory files in dirpath.
Note that the names in the lists are just names, with no path components.
To get a full path (which begins with top) to a file or directory in
dirpath, do os.path.join(dirpath, name).
# os.system(在python脚本中执行shell命令) # Execute the command (a string) in a subshell. # eg: a = os.system('echo "this is py"') print a 注意: filename = 'demo2' path = './' os.system('rm -rf '+path+filename+'/*') 【-rf 后面一定要留一个空格出来否则会报错】
os.system()函数无法返回命令的输出。只会返回C函数运行成功与否的0或其他值。
判断路径或文件
os.path.join:join(a, *p)
Join two or more pathname components, inserting '/' as needed.If any component is an absolute path, all previous path components will be discarded.
An empty last part will result in a path that ends with a separator.
os.path.isabs(...) # 判断是否绝对路径 Test whether a path is absolute
os.path.exists(...) # 判断是否真实存在 exists(path) Test whether a path exists. Returns False for broken symbolic links
os.path.isdir(...) # 判断是否是个目录 Return true if the pathname refers to an existing directory
os.path.isfile(...) # 判断是否是个文件 isfile(path) Test whether a path is a regular file
注意: 把两个路径合成一个时,不要直接拼字符串,而要通过 os.path.join(part1,part2) 函数,这样可以正确处理不同操作系统的路径分隔符。在Linux/Unix/Mac下,os.path.join()返回这样的字符串 part1/part2而Windows下会返回这样的字符串: part1part2
路径名、文件名分隔
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 -> 同意使用 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) ") 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) ") 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 ') >>> a = subprocess.run(["ls"],stdout=subprocess.PIPE) >>> print(a) CompletedProcess(args=['ls'], returncode=0, stdout=b'run_server.py ') >>> print(a.stdout,a.args,a.returncode) # 可以对返回值进行操作 b'run_server.py ' ['ls'] 0
#!/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 )," ") 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 + " " + " " 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] ' % (key_word, cmd)) logger1.critical('process[%s] is lost, run [%s] ' % (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
交互式输入 并不是所有的操作系统命令都像‘dir’或者‘ipconfig’那样单纯地返回执行结果,还有很多像‘python’这种交互式的命令,你要输入点什么,然后它返回执行的结果。使用run()方法怎么向stdin里输入? # 错误示例: import subprocess ret = subprocess.run("python", stdin=subprocess.PIPE, stdout=subprocess.PIPE,shell=True) ret.stdin = "print('haha')" # 错误的用法 print(ret) # 这样是不行的,ret作为一个CompletedProcess对象,根本没有stdin属性。那怎么办呢?前面说了,run()方法的stdin参数可以接收一个文件句柄。比如在一个1.txt文件中写入print('i like Python')。然后参考下面的使用方法: import subprocess fd = open("d:\1.txt") ret = subprocess.run("python", stdin=fd, stdout=subprocess.PIPE,shell=True) print(ret.stdout) fd.close() # 这样做,虽然可以达到目的,但是很不方便,也不是以代码驱动的方式。这个时候,我们可以使用Popen类。 # Popen上场 class subprocess.Popen() 用法和参数与run()方法基本类同,但是它的返回值是一个Popen对象,而不是CompletedProcess对象。 >>> ret = subprocess.Popen("dir", shell=True) >>> type(ret) <class 'subprocess.Popen'> >>> ret <subprocess.Popen object at 0x0000000002B17668> # Popen对象的stdin、stdout和stderr是三个文件句柄,可以像文件那样进行读写操作。 >>>s = subprocess.Popen("ipconfig", stdout=subprocess.PIPE, shell=True) >>>print(s.stdout.read().decode("GBK")) # 要实现前面的‘python’命令功能,可以按下面的例子操作: import subprocess s = subprocess.Popen("python", stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True) s.stdin.write(b"import os ") s.stdin.write(b"print(os.environ)") s.stdin.close() out = s.stdout.read().decode("GBK") s.stdout.close() print(out) # 通过s.stdin.write()可以输入数据,而s.stdout.read()则能输出数据。
>>> 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 run vs Popen
subprocess.run was added in Python 3.5 as a simplification over subprocess.Popen when you just want to execute a command and wait until it finishes, but you don't want to do anything else meanwhile. For other cases, you still need to use subprocess.Popen. The main difference is that subprocess.run executes a command and waits for it to finish, while with subprocess.Popen you can continue doing your stuff while the process finishes and then just repeatedly call subprocess.communicate yourself to pass and receive data to your process. Note that, what subprocess.run is actually doing is invoking for you the Popen and communicate, so you don't need to make a loop to pass/receive data nor wait for the process to finish. Check the official documentation for information of which parameters of subprocess.run are passed to Popen and which to communicate.
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:作用,转换之后写到文件中(不常用)
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:存储读取复杂数据类型(函数、对象)
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
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())
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中指定的节点
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.修改节点内容
由于修改的节点时,均是在内存中进行,其不会影响文件中的内容。所以,如果想要修改,则需要重新将内存中的内容写到文件。
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
创建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设置缩进
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=" ") 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')
日志等级:
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
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)
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:zhb7627CodeEclipse WorkSpacePythonTest est.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')。
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')
经常使用的时间方法 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
日期、时间戳互转:
# 引入模块 import time, datetime # str类型的日期转换为时间戳 # 字符类型的时间 tss1 = '2013-10-10 23:40:00' # 转为时间数组 timeArray = time.strptime(tss1, "%Y-%m-%d %H:%M:%S") print timeArray # timeArray可以调用tm_year等 print timeArray.tm_year # 2013 # 转为时间戳 timeStamp = int(time.mktime(timeArray)) print timeStamp # 1381419600 # 结果如下 time.struct_time(tm_year=2013, tm_mon=10, tm_mday=10, tm_hour=23, tm_min=40, tm_sec=0, tm_wday=3, tm_yday=283, tm_isdst=-1) 2013 1381419600 # 更改str类型日期的显示格式 tss2 = "2013-10-10 23:40:00" # 转为数组 timeArray = time.strptime(tss2, "%Y-%m-%d %H:%M:%S") # 转为其它显示格式 otherStyleTime = time.strftime("%Y/%m/%d %H:%M:%S", timeArray) print otherStyleTime # 2013/10/10 23:40:00 tss3 = "2013/10/10 23:40:00" timeArray = time.strptime(tss3, "%Y/%m/%d %H:%M:%S") otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray) print otherStyleTime # 2013-10-10 23:40:00 # 时间戳转换为指定格式的日期 # 使用time timeStamp = 1381419600 timeArray = time.localtime(timeStamp) otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray) print otherStyleTime # 2013--10--10 23:40:00 # 使用datetime timeStamp = 1381419600 dateArray = datetime.datetime.utcfromtimestamp(timeStamp) otherStyleTime = dateArray.strftime("%Y--%m--%d %H:%M:%S") print otherStyleTime # 2013--10--10 15:40:00 # 获取当前时间并且用指定格式显示 # time获取当前时间戳 now = int(time.time()) # 1533952277 timeArray = time.localtime(now) print timeArray otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray) print otherStyleTime # 结果如下 time.struct_time(tm_year=2018, tm_mon=8, tm_mday=11, tm_hour=9, tm_min=51, tm_sec=17, tm_wday=5, tm_yday=223, tm_isdst=0) 2018--08--11 09:51:17 # datetime获取当前时间,数组格式 now = datetime.datetime.now() print now otherStyleTime = now.strftime("%Y--%m--%d %H:%M:%S") print otherStyleTime # 结果如下: 2018-08-11 09:51:17.362986 2018--08--11 09:51:17
获取最近一个月每天的日期:
#coding:utf-8 # from common.contest import * import datetime import time begin_date = (datetime.datetime.now() - datetime.timedelta(days =30)).strftime("%Y-%m-%d") date_list = [] begin_date = datetime.datetime.strptime(begin_date, "%Y-%m-%d") end_date = datetime.datetime.strptime(time.strftime('%Y-%m-%d',time.localtime(time.time())), "%Y-%m-%d") while begin_date <= end_date: date_str = begin_date.strftime("%Y-%m-%d") date_list.append(date_str) begin_date += datetime.timedelta(days=1) print date_list C:Python27python.exe E:/squid_frame/weibo_pc_spider_local/test.py ['2019-03-18', '2019-03-19', '2019-03-20', '2019-03-21', '2019-03-22', '2019-03-23', '2019-03-24', '2019-03-25', '2019-03-26', '2019-03-27', '2019-03-28', '2019-03-29', '2019-03-30', '2019-03-31', '2019-04-01', '2019-04-02', '2019-04-03', '2019-04-04', '2019-04-05', '2019-04-06', '2019-04-07', '2019-04-08', '2019-04-09', '2019-04-10', '2019-04-11', '2019-04-12', '2019-04-13', '2019-04-14', '2019-04-15', '2019-04-16', '2019-04-17'] Process finished with exit code 0
# 时间、字符串互转 https://www.cnblogs.com/alfred0311/p/7885349.html def time_format(time_str): """ str -> datetime""" if 'T' in time_str: if '+08:00' in time_str: UTC_FORMAT = "%Y-%m-%dT%H:%M:%S+08:00" return datetime.datetime.strptime(time_str, UTC_FORMAT) if 'Z' in time_str: UTC_FORMAT = "%Y-%m-%dT%H:%M:%SZ" return datetime.datetime.strptime(time_str, UTC_FORMAT) + datetime.timedelta(hours=8) else: UTC_FORMAT = "%Y-%m-%d %H:%M:%S" return datetime.datetime.strptime(time_str, UTC_FORMAT)
# Python time & datetime & string 相互转换 #!/usr/bin/env python # -*- coding:utf-8 -*- # @Datetime : 2017/11/23 下午12:37 # @Author : Alfred Xue # @E-Mail : Alfred.Hsueh@gmail.com # @GitHub : https://github.com/Alfred-Xue # @Blog : http://www.cnblogs.com/alfred0311/ import datetime import time # 日期时间字符串 st = "2017-11-23 16:10:10" # 当前日期时间 dt = datetime.datetime.now() # 当前时间戳 sp = time.time() # 1.把datetime转成字符串 def datetime_toString(dt): print("1.把datetime转成字符串: ", dt.strftime("%Y-%m-%d %H:%M:%S")) # 2.把字符串转成datetime def string_toDatetime(st): print("2.把字符串转成datetime: ", datetime.datetime.strptime(st, "%Y-%m-%d %H:%M:%S")) # 3.把字符串转成时间戳形式 def string_toTimestamp(st): print("3.把字符串转成时间戳形式:", time.mktime(time.strptime(st, "%Y-%m-%d %H:%M:%S"))) # 4.把时间戳转成字符串形式 def timestamp_toString(sp): print("4.把时间戳转成字符串形式: ", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(sp))) # 5.把datetime类型转外时间戳形式 def datetime_toTimestamp(dt): print("5.把datetime类型转外时间戳形式:", time.mktime(dt.timetuple())) # 1.把datetime转成字符串 datetime_toString(dt) # 2.把字符串转成datetime string_toDatetime(st) # 3.把字符串转成时间戳形式 string_toTimestamp(st) # 4.把时间戳转成字符串形式 timestamp_toString(sp) # 5.把datetime类型转外时间戳形式 datetime_toTimestamp(dt)