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

时间:2021-11-11 04:52:13

pathlib:

pathlib介绍-比os.path更好的路径处理方式:https://zhuanlan.zhihu.com/p/33524938

os:

 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息
os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
 import os

 print(__file__)
print(os.path.dirname(__file__)) # 取python文件路径名、目录名
print(os.path.dirname(os.path.dirname(__file__))) # 返回上一级目录
print(os.path.basename(__file__)) # 取python文件文件名
# 输出:
C:/Users/w/PycharmProjects/python/hashlib/0718.py
C:/Users/w/PycharmProjects/python/hashlib
C:/Users/w/PycharmProjects/python
0718.py
 # -*- coding: utf-8 -*-

 import os
import sys
#from bin import s3 print(os.path.dirname(__file__))
print(os.path.basename(__file__)) p1 = os.path.dirname(__file__)
p2 = 'bin'
p = os.path.join(p1, p2)
print(p) sys.path.append(p) # 相比于下面的添加路径方法,好处在于改了路径名,不需改代码
#sys.path.append(r'C:\Users\w\PycharmProjects\python\hashlib\bin') for i in sys.path: # 默认根据列表中的路径找模块
print(i)
print('-------------------------') import s3
s3.test() 输出:
C:/Users/w/PycharmProjects/python/hashlib
0718.py
C:/Users/w/PycharmProjects/python/hashlib\bin
C:\Users\w\PycharmProjects\python\hashlib
C:\Users\w\PycharmProjects
C:\Users\w\AppData\Local\Programs\Python\Python35\python35.zip
C:\Users\w\AppData\Local\Programs\Python\Python35\DLLs
C:\Users\w\AppData\Local\Programs\Python\Python35\lib
C:\Users\w\AppData\Local\Programs\Python\Python35
C:\Users\w\AppData\Local\Programs\Python\Python35\lib\site-packages
C:/Users/w/PycharmProjects/python/hashlib\bin
-------------------------
=======in s3========

模块路径添加方法

 import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), 'bin'))

一行代码添加路径

 import sys
import os #导入父目录下的另一个目录到系统路径sys.path 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下会返回这样的字符串: part1\part2

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

这些合并、拆分路径的函数并不要求目录和文件要真实存在,它们只对字符串进行操作。

工作目录及创建文件夹操作
os.getcwd()      # 获取当前工作目录
os.chdir(...)     # 改变工作目录 chdir(path)
os.listdir(...)    # 列出目录下的文件 listdir(path)
os.mkdir(...)     # 创建单个目录 mkdir(path [, mode=0777])#测试时好像不支持权限参数     注意:创建多级用 os.makedirs()
os.makedirs(...)   # 创建多级目录 makedirs(path [, mode=0777]) mkdir recursive.

创建文件夹可能会出错,原因具体有:(1) path 已存在时(不管是文件还是文件夹) (2) 驱动器不存在 (3) 磁盘已满 (4) 磁盘是只读的或没有写权限

删除文件夹/文件

os.rmdir(...)         # 删除空文件夹 注意:必须为空文件夹 如需删除文件夹及其下所有文件,需用 shutil
os.remove(...) # 删除单一文件
shutil.rmtree(...) # 删除文件夹及其下所有文件

tip1:清空指定文件夹下所有文件的方法

需要在执行某些代码前清空指定的文件夹,如果直接用os.remove(),可能出现因文件夹中文件被占用而无法删除,解决方法也很简单,先强制删除文件夹,再重新建同名文件夹即可

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

产生异常的可能原因: (1) 路径不存在 (2) 路径子目录中有文件或下级子目录(os.rmdir) (3) 没有操作权限或只读

tip2:把一个文件从一个文件夹移动到另一个文件夹,并同时重命名,用shutil:

  shutil.move('原文件夹/原文件名','目标文件夹/目标文件名')

重命名文件夹/文件
可对某一文件或文件夹重命名 os.rename(oldfileName, newFilename)
注意:新文件的扩展名不能遗漏,理论上需要保持类型一致;但这也不失为改文件类型的一种方式(相当于直接改文件的扩展名)

shutil

复制、移动文件夹/文件 :(new不指定路径,默认放到家目录)
shutil.copyfile("old","new")      # (不copy权限)复制文件,都只能是文件 copyfile(src, dst) 注意:不会保持源文件权限,如果存在new会强制覆盖!!!
shutil.copytree("old","new")     # 复制文件夹,都只能是目录,且new必须不存在 Recursively copy a directory tree using copy2() 保持源文件信息
shutil.copy("old","new")     # (copy权限)复制文件/文件夹,复制 old 为 new(new是文件,若不存在,即新建,存在则覆盖!),复制 old 为至 new 文件夹(文件夹已存在),相当于 cp src dst
shutil.move("old","new")      # 移动文件/文件夹至 new 文件夹中 同Unix下的mv命令
shutil.copy2(src, dst) #只能复制文件,只保留stat信息 Copy data and all stat info ("cp -p src dst") The destination may be a directory

 import shutil

 # 高级的 文件、文件夹、压缩包 处理模块
shutil.copyfileobj(open('log.log', 'r'), open('new_log.log', 'w')) # 将文件内容拷贝到另一个文件中 # 仅拷贝权限。内容、组、用户均不变 shutil.copymode(src, dst)
shutil.copymode('f1.log', 'f2.log') # 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags shutil.copystat(src, dst)
shutil.copystat('f1.log', 'f2.log') # 递归的去拷贝文件夹 shutil.copytree(src, dst, symlinks=False, ignore=None)
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
# 拷贝源文件,还是只拷贝软连接,用symlinks参数调节
shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) # 创建压缩包并返回文件路径,例如:zip、tar
# shutil.make_archive(base_name, format,...) base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如:www =>保存至当前路径
如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
root_dir: 要压缩的文件夹路径(默认当前目录)
owner: 用户,默认当前用户
group: 组,默认当前组
logger: 用于记录日志,通常是logging.Logger对象 #将 /Users/wupeiqi/Downloads/test 下的文件打包放入www.gztar文件,放置当前程序目录
ret = shutil.make_archive("www", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') #将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录
ret = shutil.make_archive("/Users/wupeiqi/www", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') # shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
#处理zip包
import zipfile
# 压缩
z = zipfile.ZipFile('laxi.zip', 'w') # w方式创建,默认清空压缩包中的文件
z.write('a.log')
z.write('data.data') # 添加单独的文件到压缩包中
z.close() # 解压
z = zipfile.ZipFile('laxi.zip', 'r')
r = z.namelist() # 获取压缩文件列表
z.extractall() # 没有文件名,默认解压全部文件,有文件名,则解压单独文件
z.close() #处理tar包
import tarfile
# 压缩
tar = tarfile.open('your.tar','w')
tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log')
tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log')
tar.close() # 解压
tar = tarfile.open('your.tar','r')
tar.extractall() # 可设置解压地址
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模块

 import subprocess

 call方法:执行命令,返回状态码
ret = subprocess.call(["ls", "-l"], shell=False) # shell为False时,会把命令解析为一个字符,所以要以列表形式输入
ret1 = subprocess.call("ls -l", shell=True) # check_call方法:执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
subprocess.check_call(["ls", "-l"])
subprocess.check_call("exit 1", shell=True) # check_output:执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
subprocess.check_output(["echo", "Hello World!"])
subprocess.check_output("exit 1", shell=True) # Popen方法:用于执行复杂的系统命令,程序不会阻塞,而subprocess.run是阻塞的
参数:
args:shell命令,可以是字符串或者序列类型(如:list,元组)
bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
shell:同上
cwd:用于设置子进程的当前目录
env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等 # 执行普通命令:
ret1 = subprocess.Popen(["mkdir","t1"])
ret2 = subprocess.Popen("mkdir t2", shell=True) 终端输入的命令分为两种: 输入即可得到输出,如:ifconfig
输入进行某环境,依赖再输入,如:python ,进入python交互环境 # 通过Popen创建目录:
obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',) # 用于设置子进程的当前目录 # 通过subprocess.PIPE进行交互输入命令、读取(正确/错误)结果[因为subprocess是新启动一个进程,如果主进程想要获取子进程的结果(进程间通信),就要通过管道/socket来实现:即PIPE]
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
obj.stdin.write("print(1)\n")
obj.stdin.write("print(2)")
obj.stdin.close() cmd_out = obj.stdout.read()
obj.stdout.close()
cmd_error = obj.stderr.read()
obj.stderr.close() print(cmd_out)
print(cmd_error) # 通过communicate多次单条命令交互
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
obj.stdin.write("print(1)\n")
obj.stdin.write("print(2)") out_error_list = obj.communicate() # 相当于去读管道中的内容,obj.stdout.read(),obj.stderr.read(),并把读到的内容进行拼接,其中包含输出和错误输出
print(out_error_list) # 单条命令直接通过communicate执行,并从中获取结果
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
out_error_list = obj.communicate('print("hello")')
print(out_error_list)
subprocess
该子模块允许你创建新的流程,连接到它们的输入/输出/错误管道,并获取他们的返回值。该模块打算替换多个旧的模块和功能:os.system 和 os.spawn *
使用subprocess时建议使用run()函数去处理所有它可以处理的情况,因为高级用法可以直接使用底层POPEN接口。
run()函数是Python 3.5中新添加的。
使用方法:
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False)
args 该参数用于启动进程。这可能是一个列表或一个字符串。 returncode 该参数表示子进程的退出状态。
通常情况下,0作为退出状态表明它成功运行。
负值-N表明子进程被信号N终止(仅POSIX)。 stdout 该参数表示标准输出
从子过程中捕获标准输出。一个字节序列,或字符串 ()如果运行一个字符串被称为与universal_newlines = TRUE。无如果stdout没有抓获。 如果您运行进程与标准错误= subprocess.STDOUT,输出和错误将在此属性相结合,和stderr将是无。 标准错误 从子过程中捕获标准错误。一个字节序列,或()如果运行一个字符串被称为与universal_newlines = TRUE。无标准错误,如果没有抓获。 check_returncode() 如果返回码不为零,养CalledProcessError。 先看个例子:
>>> import subprocess
>>> subprocess.run(["ls"])
run_server.py # ls命令返回的结果
CompletedProcess(args=['ls'], returncode=0) # run函数返回的结果
>>> subprocess.run(["ls", "-l"]) # 这个和上面的类似
总用量 4
-rw-r--r-- 1 root root 266 9月 22 14:35 run_server.py
CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run(["ls"],stdout=subprocess.PIPE) # 加上stdout参数之后,系统命令返回的结果就不会输出了
CompletedProcess(args=['ls'], returncode=0, stdout=b'run_server.py\n') >>> a = subprocess.run(["ls"],stdout=subprocess.PIPE)
>>> print(a)
CompletedProcess(args=['ls'], returncode=0, stdout=b'run_server.py\n')
>>> print(a.stdout,a.args,a.returncode) # 可以对返回值进行操作
b'run_server.py\n' ['ls'] 0

subprocess run方法

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import subprocess
import sys
import smtplib
import string
import time
import subprocess
import datetime
from smtplib import SMTP_SSL
from email.header import Header
from email.mime.text import MIMEText
import socket #logging.basicConfig(filename='process_log',
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=10) file_1_1 = logging.FileHandler('/var/log/process_log.log', 'a', encoding='utf-8')
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")
file_1_1.setFormatter(fmt) logger1 = logging.Logger('recommend-node1-doyo-feedstream-go', level=logging.ERROR)
logger1.addHandler(file_1_1) fail_check = 0
check_interval = 5 reload(sys)
sys.setdefaultencoding('utf-8')
text = ''
datetime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
hostname = socket.gethostname() def S_Mail(text):
HOST = "smtp.exmail.qq.com"
SUBJECT = 'DOYO Process Monitor'.decode('utf-8').encode('gbk')
TO = 'whisky@doyo.tv'
FROM = "monitor@douyu.tv"
BODY = string.join((
"FROM: %s" % FROM,
"To: %s" % TO,
"Subject: %s" %SUBJECT,
"",
text
),"\r\n")
smtp = smtplib.SMTP_SSL(HOST,465)
smtp.ehlo()
smtp.login("monitor@douyu.tv","Hello123456")
smtp.sendmail(FROM,[TO],BODY)
smtp.quit() with open('/tmp/py_Email.log','a') as f:
date=time.strftime("%y-%m-%d %H:%M:%S")
str = date + " " + TO +" " + SUBJECT + "\r\n" + "\n"
str1 = str.decode('gbk').encode('utf-8')
# print("%s" %str1)
f.write(str1) def monitor_process(key_word, cmd, fail_check):
p1 = subprocess.Popen(['ps', '-ef'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', key_word], stdin=p1.stdout, stdout=subprocess.PIPE)
p3 = subprocess.Popen(['grep', '-v', 'grep'], stdin=p2.stdout, stdout=subprocess.PIPE)
p4 = subprocess.Popen(['egrep', '-v', 'doyo-feedstream-go.log|su www'], stdin=p3.stdout, stdout=subprocess.PIPE) lines = p4.stdout.readlines()
if len(lines) > 0: # process is ok
return
else:
time.sleep(check_interval)
fail_check += 1
if fail_check < 4:
return monitor_process(key_word, cmd, fail_check)
else:
pass
sys.stderr.write('process[%s] is lost, run [%s]\n' % (key_word, cmd))
logger1.critical('process[%s] is lost, run [%s]\n' % (key_word, cmd))
#subprocess.call(cmd,env={'JAVA_HOME': '/usr/java/jdk1.8.0_181/'}, shell=True)
subprocess.call(cmd, shell=True)
msg = 'hostname:{0} msg: process:{1} is lost, run {2} , time: {3}'.format(hostname, key_word, cmd, datetime).decode('utf-8').encode('gbk')
S_Mail(msg) if __name__ == '__main__':
#monitor_process('doyo-feedstream-go', 'cd /data/doyo-feedstream-go/; su www -s nohup ./doyo-feedstream-go &', fail_check)
monitor_process('doyo-feedstream-go', 'cd /data/doyo-feedstream-go/; su www -s ./doyo-feedstream-go &> /dev/null &', fail_check) # no startup.sh,use non-nohup , command finished,su www will exit

subprocess进程检测脚本

交互式输入
并不是所有的操作系统命令都像‘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\n")
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()则能输出数据。

subprocess的stdin参数应用

>>> ret = subprocess.getoutput('ls -l')
>>> print(ret)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l')
>>> print(retcode)
0
>>> print(output)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l /test')
>>> print(retcode)
2
>>> print(output)
ls: 无法访问/test: 没有那个文件或目录

subprocess.getoutput()与subprocess.getstatusoutput()

sys模块

 sys.argv           命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0)
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
sys.stdout.write('please:')
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方法)

 import json

 s = '{"desc":"invilad-citykey","status":1002}'  # 这种形似列表或字典或元组的字符串(s是由单引号括起来的字符串),内部元素如果是字符串,必须要加双引号(单引号会报错,如果交给json处理)
l = '[11, 22, 33, 44]'
result = json.loads(s) # 将一个形似列表或字典或元组的字符串,转换成列表或字典(前提,字符串必须符合列表或字典或元组的的格式)
result2 = json.loads(l)
print(result, type(result))
print(result2, type(result2)) # 输出:
{'desc': 'invilad-citykey', 'status': 1002} <class 'dict'>
[11, 22, 33, 44] <class 'list'> dic = {'first': 1, "second": 2}
user_list = ['peter', 'john']
m = json.dumps(dic)
n = json.dumps(user_list)
print(m, type(m))
print(n, type(n))
#输出
{"first": 1, "second": 2} <class 'str'>
["peter", "john"] <class 'str'> 小结:
json.loads() # 将字符串-->python基本数据类型(内部必须是双引号,否则报错)
json.dumps() # 将python基本数据类型-->字符串

注意:元组在loads时会出错,元组在dumps时会变成列表。因为只有字典、列表是通用数据类型
json:本质就是字符串(内容比较特殊,是列表、字典、元组)
http请求响应内容是字符串,如果要让python处理,需用json的loads方法。

json的load,dump:作用,转换之后写到文件中(不常用)

 import json
a = '{"whisky": 666, "tom": 2333, "peter": "ok"}' dic = {"whisky": 666, "tom": 2333, "peter": "ok"}
json.dump(a, open('db', 'a+')) r = json.load(open('db', 'r'))
print(r, type(r)) # 输出:
{'tom': 2333, 'whisky': 666, 'peter': 'ok'} <class 'dict'>

load、dump

pickle:存储读取复杂数据类型(函数、对象)

 #处理复杂数据类型(函数等)的方法:pickle(只支持python,不支持Java(支持json))
import pickle def sayhi(name):
print('hello,', name)
info = {
'name': 'whitesky',
'age': 25,
'func': sayhi
} f = open('test.txt', 'wb') #pickle序列化要带b
f.write(pickle.dumps(info)) #相当于 pickle._dump(info,f) #pickle反序列化 f = open('test.txt', 'rb')
data = pickle.loads(f.read()) # 相当于 pickle.load(f) print(data['func']) f.close() #注意:写程序序列化时要记住只dump一次,只load一次(py3中dump多次,再load时会出错,py2中正常),如果需要存储多个状态,就dump成多个文件
 # -*- coding: utf-8 -*-

 import pickle

 test = [1, 2]

 def change(inner_list=[]):
inner_list += [2, 3] change(test) pickle.dump(test, open('test_pickle_file', 'wb'))
print(pickle.load(open('test_pickle_file', 'rb'))) # 输出 [1, 2, 2, 3]

XML

格式如下:

 <data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2023</year>
<gdppc>141100</gdppc>
<neighbor direction="E" name="Austria" />
<neighbor direction="W" name="Switzerland" />
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2026</year>
<gdppc>59900</gdppc>
<neighbor direction="N" name="Malaysia" />
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2026</year>
<gdppc>13600</gdppc>
<neighbor direction="W" name="Costa Rica" />
<neighbor direction="E" name="Colombia" />
</country>
</data>

1、解析XML

 from xml.etree import ElementTree as ET

 #打开文件,读取XML内容
str_xml = open('first.xml', 'r').read() #将字符串解析成xml特殊对象,root代指xml文件的根节点
root = ET.XML(str_xml) #或
root1 = ET.XML(open('first.xml', 'r', encoding='utf-8').read())

利用ElementTree.XML将字符串解析成xml对象

 from xml.etree import ElementTree as ET

 # 直接解析xml文件
tree = ET.parse('first.xml') # 获取xml文件的根节点
root = tree.getroot()

利用ElementTree.parse将文件直接解析成xml对象

 xml自闭标签:http://www.cnblogs.com/ckysea/p/4627423.html 一个XML标签就是一个XML元素。 一个XML标签分为开始标签和结束标签,在开始标签和结束标签之间的文本被称为标签体。 包含标签体:<a>www.itcast.cn</a>;                  如果一个不包含标签体也不包含其他元素,那么可以将开始标签和结束标签合并,这样的标签称为自闭标签 不含标签体及其他元素:<a></a>可以简写为自闭标签:<a/>
小结:
tree:
1.由ELementTree创建 ElementTree(xxx)
2.getroot() 获取xml根节点
3. write()内存中的xml写入文件中

2、操作XML

a. 遍历XML文档的所有内容,遍历XML中指定的节点

 from xml.etree import ElementTree as ET

 # a.遍历XML文档的所有内容
'''
############ 解析方式一:ElementTree.XML ############
str_xml = open('first.xml', 'r').read()
root = ET.XML(str_xml)
'''
############ 解析方式二:ElementTree.parse ############
tree = ET.parse('first.xml')
root = tree.getroot() # print(root.tag) # 顶层标签 for second_tag in root:
print(second_tag.tag, second_tag.attrib)
for third_tag in second_tag:
print(third_tag.tag, third_tag.text) # b.遍历XML中指定的节点
# 遍历XML中所有的year节点
for node in root.iter('year'):
print(node.attrib, node.text)

 b.修改节点内容

由于修改的节点时,均是在内存中进行,其不会影响文件中的内容。所以,如果想要修改,则需要重新将内存中的内容写到文件。
 ######## 解析方式一:ElementTree.XML ########
str_xml = open('first.xml', 'r').read()
root = ET.XML(str_xml)
print(root.tag) # 顶层标签
# 循环所有的year节点
for node in root.iter('year'):
new_year = int(node.text) + 1
node.text = str(new_year)
# 设置属性
node.set('name', 'alex')
node.set('age', '')
# 删除属性
del node.attrib['name'] ############ 保存文件 ############
tree = ET.ElementTree(root)
tree.write("newnew.xml", encoding='utf-8') ##### 解析方式二:ElementTree.parse #####
tree = ET.parse('first.xml')
root = tree.getroot()
# 修改节点方法同方式一
# 保存文件方式和一有区别
tree.write("newnew.xml", encoding='utf-8')

两种方式修改、保存节点的内容

tree作用总结:

 xml自闭标签:http://www.cnblogs.com/ckysea/p/4627423.html 一个XML标签就是一个XML元素。 一个XML标签分为开始标签和结束标签,在开始标签和结束标签之间的文本被称为标签体。 包含标签体:<a>www.itcast.cn</a>;                  如果一个不包含标签体也不包含其他元素,那么可以将开始标签和结束标签合并,这样的标签称为自闭标签 不含标签体及其他元素:<a></a>可以简写为自闭标签:<a/>
小结:
tree的作用:
1.由ELementTree创建 ElementTree(root根节点)
2.getroot方法,获取xml根节点
3. write()内存中的xml写入文件中,要保存xml字符串必须要有tree

创建tree的方式:

 创建tree的两种方式:
tree = ET.parse('文件名')
tree = ET.ElementTree(根节点(Element对象))

c.删除节点(remove方法只能删除子节点,所以remove前要先找到父节点,通过父节点删除子节点)

 from xml.etree import ElementTree as ET
############ 解析字符串方式打开 ############
str_xml = open('first.xml', 'r').read()
root = ET.XML(str_xml) # root代指xml文件的根节点data print(root.tag)
# 遍历data下的所有country节点
for node in root.findall('country'): # findall/find不能跨节点查找,只能从最外层逐层查找
for s in node.findall('year'):
node.remove(s) tree = ET.ElementTree(root)
tree.write("newnew.xml", encoding='utf-8')

解析字符串方式打开

 from xml.etree import ElementTree as ET
tree = ET.parse('first.xml')
root = tree.getroot() for country in root.findall('country'):
for s in country.findall('rank'):
rank = int(country.find('rank').text)
if rank > 50:
country.remove(s) # rank节点大于50的删除 tree.write("newnew.xml", encoding='utf-8')

解析文件方式

3、创建XML文档

 # 创建XML文档
from xml.etree import ElementTree as ET
# 创建根节点
root = ET.Element('family') # 创建节点老大
son1 = root.makeelement('son', {'name': '老大'})
# 或
# son1 = ET.Element('son', {'name': '儿1'}) #创建老二
son2 = root.makeelement('son', {'name': '老二'})
# 或
# son2 = ET.Element('son', {"name": '儿2'}) #在老大中创建两个孙子节点
grandson1 = ET.Element('grandson', {'name': '儿11'})
grandson2 = ET.Element('grandson', {'name': '儿22'})
#或
# grandson1 = son1.makeelement('grandson', {'name': '儿11'})
# grandson2 = son1.makeelement('grandson', {'name': '儿12'})
son1.append(grandson1)
son1.append(grandson2) #添加老大到根节点
root.append(son1)
root.append(son2) tree = ET.ElementTree(root)
tree.write('0815.xml',encoding='utf-8')

创建方式一

 from xml.etree import ElementTree as ET

 # 创建根节点
root = ET.Element("famliy") # 创建节点大儿子
son1 = ET.SubElement(root, "son", attrib={'name': '儿1'})
# 创建小儿子
son2 = ET.SubElement(root, "son", attrib={"name": "儿2"}) # 在大儿子中创建一个孙子
grandson1 = ET.SubElement(son1, "age", attrib={'name': '儿11'})
grandson1.text = '孙子' et = ET.ElementTree(root) #生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True, short_empty_elements=False) 创建方式(三)

方式二

 <family>
<son name="老大">
<grandson name="儿11" />
<grandson name="儿22" />
</son>
<son name="老二" />
</family>

创建好的XML

XML设置缩进

 from xml.etree import ElementTree as ET
from xml.dom import minidom def prettify(elem):
"""将节点转换成字符串,并添加缩进。
"""
rough_string = ET.tostring(elem, 'utf-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent="\t") # 创建根节点
root = ET.Element("famliy") # 创建大儿子
# son1 = ET.Element('son', {'name': '儿1'})
son1 = root.makeelement('son', {'name': '儿1'})
# 创建小儿子
# son2 = ET.Element('son', {"name": '儿2'})
son2 = root.makeelement('son', {"name": '儿2'}) # 在大儿子中创建两个孙子
# grandson1 = ET.Element('grandson', {'name': '儿11'})
grandson1 = son1.makeelement('grandson', {'name': '儿11'})
# grandson2 = ET.Element('grandson', {'name': '儿12'})
grandson2 = son1.makeelement('grandson', {'name': '儿12'}) son1.append(grandson1)
son1.append(grandson2) # 把儿子添加到根节点中
root.append(son1)
root.append(son1) raw_str = prettify(root) f = open("xxxoo.xml",'w',encoding='utf-8')
f.write(raw_str)
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
 import configparser

 # 获取所有节点的值
config = configparser.ConfigParser()
config.read('ini', encoding='utf-8') # 读到内存当中
ret = config.sections() # 获取所有节点的值
print(ret)
# 输出:['section1', 'section2', 'test_ansible'] # 获取指定节点下所有的键值对
config = configparser.ConfigParser()
config.read('ini', encoding='utf-8')
ret = config.items('test_ansible') # 获取指定节点下所有的键值对
print(ret)
# 输出[('node1', '192.168.2.3'), ('ansible_ssh_port', '22'), ('ansible_ssh_user', 'gxy_ansible'), ('ansible_su_pass', '123456'), ('汉字', '123')] # 获取指定节点下所有的键
config = configparser.ConfigParser()
config.read('ini',encoding='utf-8')
ret = config.options('test_ansible') # 获取指定节点下所有的键
print(ret)
# 输出:['node1', 'ansible_ssh_port', 'ansible_ssh_user', 'ansible_su_pass', '汉字'] # 获取指定节点下指定key的值
config = configparser.ConfigParser()
config.read('ini', encoding='utf-8')
value = config.get('test_ansible', 'node1') # 获取指定节点下指定key的值
# v = config.getint('test_ansible', 'ansible_su_pass') # 字符串转换为整形
# v1 = config.getfloat('test_ansible', 'ansible_su_pass')
# v2 = config.getboolean('test_ansible', 'node1')
print(value)
# 输出: 192.168.2.3 # 检查、删除、添加节点
config = configparser.ConfigParser()
config.read('ini', encoding='utf-8')
# 检查
has_sec = config.has_section('test_ansible')
print(has_sec) # 输出: True
# 添加节点
config.add_section('test_ansible_new')
config.write(open('new_ini', 'w', encoding='utf-8'))
# 删除节点
config.remove_section('section2')
config.write(open('new_ini', 'w', encoding='utf-8')) # 检查、删除、设置指定组内的键值对
config = configparser.ConfigParser()
config.read('ini', encoding='utf-8') has_opt = config.has_option('test_ansible', '汉字') # 检查,('键','值')
print(has_opt) config.remove_option('section1', 'k1')
config.write(open('delete_ini', 'w', encoding='utf-8')) config.set('section1', 'k2', '') # 设置, 有则改,没有则新增
config.write(open('set_ini', 'w', encoding='utf-8'))

logging模块(用于便捷记录日志且线程安全的模块):

单文件日志

 import logging

 logging.basicConfig(filename='log.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=10) logging.debug('debug')
logging.info('info')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
logging.log(10,'log')

日志等级:

 CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

注:只有【当前写等级level】大于【日志等级】时,日志文件才被记录。

多文件日志

对于上述记录日志的功能,只能将日志记录在单文件中,如果想要设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件和日志操作对象。

 # 定义文件
file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")
file_1_1.setFormatter(fmt) file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
fmt = logging.Formatter()
file_1_2.setFormatter(fmt) # 定义日志
logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_1_1) #两个日志文件全部加入logger1文件对象中,则记录日志时,会同时写入两个文件
logger1.addHandler(file_1_2) # 写日志
logger1.critical('')
 # 定义文件
file_2_1 = logging.FileHandler('l2_1.log', 'a')
fmt = logging.Formatter()
file_2_1.setFormatter(fmt) # 定义日志
logger2 = logging.Logger('s2', level=logging.INFO)
logger2.addHandler(file_2_1)

日志(二)

如上述创建的两个日志对象

  • 当使用【logger1】写日志时,会将相应的内容写入 l1_1.log 和 l1_2.log 文件中
  • 当使用【logger2】写日志时,会将相应的内容写入 l2_1.log 文件中
 import logging

 # 日志配置:
logging.basicConfig(filename='log.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=10) # 日志记录的方法:
logging.debug('debug') # 内部调用的logging.log, 相当于logging.log(10,'debug')
logging.info('info')
logging.warning('warning') # 建议用这
logging.error('error')
logging.critical('critical')
logging.log(10,'log') # 定义文件
#创建第一个文件对象(FileHandler方法)
file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8') # 定义文件名为:l1_1.log
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s") # logging.Formatter格式化处理
file_1_1.setFormatter(fmt) #创建第二个文件对象
file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
fmt = logging.Formatter()
file_1_2.setFormatter(fmt) # 定义日志
#创建写日志的对象
logger1 = logging.Logger('s1', level=logging.ERROR) # s1会写到logging.Formatter的%(name)处
logger1.addHandler(file_1_1) # 将文件对象加入写日志的对象中,用于写日志
logger1.addHandler(file_1_2) # 写日志
logger1.critical('') # 关联了上面两个文件(file_1_1和file_1_2),所以一条日志信息会同时写入上面两个文件中 # 实战:
同时定义两个日志文件,
# 定义文件
file_1_1 = logging.FileHandler('run.log', 'a', encoding='utf-8') # 定义文件名为:run.log
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")
file_1_1.setFormatter(fmt) # 定义日志
logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_1_1) # 写日志
logger1.critical('') # 定义文件
file_1_1 = logging.FileHandler('error.log', 'a', encoding='utf-8') # 定义文件名为:error.log
fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")
file_1_1.setFormatter(fmt) # 定义日志
logger1 = logging.Logger('s1', level=logging.ERROR)
logger1.addHandler(file_1_1) # 写日志
logger1.critical('') CMDB中的应用:
def initialize_run_log(self):
self.check_path_exist(self.run_log_file)
file_1_1 = logging.FileHandler(self.run_log_file, 'a', encoding='utf-8') # 文件对象
fmt = logging.Formatter(fmt="%(asctime)s - %(levelname)s : %(message)s") # 设置日志格式
file_1_1.setFormatter(fmt) # 设置日志格式
logger1 = logging.Logger('run_log', level=logging.INFO)
logger1.addHandler(file_1_1)
self.run_logger = logger1 def initialize_error_log(self):
self.check_path_exist(self.error_log_file)
file_1_1 = logging.FileHandler(self.error_log_file, 'a', encoding='utf-8')
fmt = logging.Formatter(fmt="%(asctime)s - %(levelname)s : %(message)s")
file_1_1.setFormatter(fmt)
logger1 = logging.Logger('run_log', level=logging.ERROR)
logger1.addHandler(file_1_1)
self.error_logger = logger1 def log(self, message, mode=True):
"""
写入日志
:param message: 日志信息
:param mode: True表示运行信息,False表示错误信息
:return:
"""
if mode:
self.run_logger.info(message)
else:
self.error_logger.error(message)

logging方法实践

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

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

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

https://www.jianshu.com/p/d615bf01e37b     多进程日志 

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

traceback捕获并打印异常:

 异常处理是日常操作了,但是有时候不能只能打印我们处理的结果,还需要将我们的异常打印出来,这样更直观的显示错误
下面来介绍traceback模块来进行处理
try:
1/0
except Exception, e:
print e
输出结果是integer division or modulo by zero,只知道是报了这个错,但是却不知道在哪个文件哪个函数哪一行报的错。 使用traceback
try:
1/0
except Exception, e:
traceback.print_exc()
Traceback (most recent call last): File "test_traceback.py", line 3, in <module> 1/0 ZeroDivisionError: integer division or modulo by zero # 这样非常直观有利于调试。 # traceback.print_exc()跟traceback.format_exc()有什么区别呢?
print_exc()则直接给打印出来;
format_exc()返回字符串;
即traceback.print_exc()与print traceback.format_exc()效果是一样的。
print_exc()还可以接受file参数直接写入到一个文件。
比如:
traceback.print_exc(file=open('tb.txt','w+')) # 写入到tb.txt文件去。
 也可以使用logger.exception(msg,_args),它等价于logger.error(msg,exc_info = True,_args),

 将

 logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)
替换为, logger.exception("Failed to open sklearn.txt from logger.exception")
控制台和日志文件log.txt中输出, Start print log
Something maybe fail.
Failed to open sklearn.txt from logger.exception
Traceback (most recent call last):
File "G:\zhb7627\Code\Eclipse WorkSpace\PythonTest\test.py", line 23, in <module>
open("sklearn.txt","rb")
IOError: [Errno 2] No such file or directory: 'sklearn.txt'
Finish
 import和__import__()有什么不同?

 import作用:
导入/引入一个python标准模块,其中包括.py文件、带有__init__.py文件的目录; __import__作用:
同import语句同样的功能,但__import__是一个函数,并且只接收字符串作为参数,所以它的作用就可想而知了。其实import语句就是调用这个函数进行导入工作的,import sys <==>sys = __import__('sys')。

import和__import__()

 s.rsplit()和s.split()区别是什么啊

 一个从左开始,一个从右开始。
如果是这样没有区别:
>>> s = 'asd dfdf ff'
>>> s.split()
['asd', 'dfdf', 'ff']
>>> s.rsplit()
['asd', 'dfdf', 'ff'] 这样就看出不同了。
>>> s.split(' ',1)
['asd', 'dfdf ff']
>>> s.rsplit(' ',1)
['asd dfdf', 'ff']

s.rsplit()和s.split()区别是什么啊

random模块:

 # random 模块
import random print(random.random())
print(random.randint(1, 2)) # Return random integer in range [a, b], including both end points.
print(random.randrange(1, 10)) # Choose a random item from range(start, stop[, step]) 不包括stop边界 # 生成随机验证码
import random
verification_code = ''
for i in range(6):
rand = random.randrange(0, 4)
if rand == 3 or rand == 1:
num = random.randint(0, 9)
verification_code += str(num)
else:
num = random.randint(65, 91)
letter = chr(num)
verification_code += letter
print(verification_code) import random
verification_code = ''
for i in range(6):
rand = random.randrange(0, 6)
if i == rand:
num = random.randint(0, 9)
verification_code += str(num)
else:
num = random.randint(65, 91)
letter = chr(num)
verification_code += letter
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 #
# 转为时间戳
timeStamp = int(time.mktime(timeArray))
print timeStamp # # 结果如下
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()) #
timeArray = time.localtime(now)
print timeArray
otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray)
print otherStyleTime # 结果如下
time.struct_time(tm_year=2018, tm_mon=8, tm_mday=11, tm_hour=9, tm_min=51, tm_sec=17, tm_wday=5, tm_yday=223, tm_isdst=0)
2018--08--11 09:51:17 # datetime获取当前时间,数组格式
now = datetime.datetime.now()
print now
otherStyleTime = now.strftime("%Y--%m--%d %H:%M:%S")
print otherStyleTime # 结果如下:
2018-08-11 09:51:17.362986
2018--08--11 09:51:17

获取最近一个月每天的日期:

#coding:utf-8
# from common.contest import * import datetime
import time
begin_date = (datetime.datetime.now() - datetime.timedelta(days =30)).strftime("%Y-%m-%d")
date_list = []
begin_date = datetime.datetime.strptime(begin_date, "%Y-%m-%d")
end_date = datetime.datetime.strptime(time.strftime('%Y-%m-%d',time.localtime(time.time())), "%Y-%m-%d")
while begin_date <= end_date:
date_str = begin_date.strftime("%Y-%m-%d")
date_list.append(date_str)
begin_date += datetime.timedelta(days=1) print date_list C:\Python27\python.exe E:/squid_frame/weibo_pc_spider_local/test.py
['2019-03-18', '2019-03-19', '2019-03-20', '2019-03-21', '2019-03-22', '2019-03-23', '2019-03-24', '2019-03-25', '2019-03-26', '2019-03-27',
'2019-03-28', '2019-03-29', '2019-03-30', '2019-03-31', '2019-04-01', '2019-04-02', '2019-04-03', '2019-04-04', '2019-04-05', '2019-04-06',
'2019-04-07', '2019-04-08', '2019-04-09', '2019-04-10', '2019-04-11', '2019-04-12', '2019-04-13', '2019-04-14', '2019-04-15', '2019-04-16',
'2019-04-17'] Process finished with exit code 0
# 时间、字符串互转
https://www.cnblogs.com/alfred0311/p/7885349.html def time_format(time_str):
""" str -> datetime"""
if 'T' in time_str:
if '+08:00' in time_str:
UTC_FORMAT = "%Y-%m-%dT%H:%M:%S+08:00"
return datetime.datetime.strptime(time_str, UTC_FORMAT)
if 'Z' in time_str:
UTC_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
return datetime.datetime.strptime(time_str, UTC_FORMAT) + datetime.timedelta(hours=8)
else:
UTC_FORMAT = "%Y-%m-%d %H:%M:%S"
return datetime.datetime.strptime(time_str, UTC_FORMAT)
# 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)

重要:python第三方库 - dateutil:

https://www.cnblogs.com/peng104/p/9890507.html