zoukankan      html  css  js  c++  java
  • day 5 模块导入、常用模块os shutil sys commands subprocess hashlib json pickle zipfile traceback random datetime pathlib

    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(),可能出现因文件夹中文件被占用而无法删除,解决方法也很简单,先强制删除文件夹,再重新建同名文件夹即可

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

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

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

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

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

    shutil

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

     1 import shutil
     2 
     3 # 高级的 文件、文件夹、压缩包 处理模块
     4 shutil.copyfileobj(open('log.log', 'r'), open('new_log.log', 'w')) # 将文件内容拷贝到另一个文件中
     5 
     6 # 仅拷贝权限。内容、组、用户均不变 shutil.copymode(src, dst)
     7 shutil.copymode('f1.log', 'f2.log')
     8 
     9 # 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags  shutil.copystat(src, dst)
    10 shutil.copystat('f1.log', 'f2.log')
    11 
    12 # 递归的去拷贝文件夹 shutil.copytree(src, dst, symlinks=False, ignore=None)
    13 shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    14 # 拷贝源文件,还是只拷贝软连接,用symlinks参数调节
    15 shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    16 
    17 # 创建压缩包并返回文件路径,例如:zip、tar
    18 # shutil.make_archive(base_name, format,...)
    19 
    20 base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    21 如:www                        =>保存至当前路径
    22 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
    23 format:    压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    24 root_dir:    要压缩的文件夹路径(默认当前目录)
    25 owner:    用户,默认当前用户
    26 group:    组,默认当前组
    27 logger:    用于记录日志,通常是logging.Logger对象
    28 
    29 #将 /Users/wupeiqi/Downloads/test 下的文件打包放入www.gztar文件,放置当前程序目录
    30 ret = shutil.make_archive("www", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
    31 
    32 #将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录
    33 ret = shutil.make_archive("/Users/wupeiqi/www", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
    34 
    35 # shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
    36 #处理zip包
    37 import zipfile
    38 # 压缩
    39 z = zipfile.ZipFile('laxi.zip', 'w')  # w方式创建,默认清空压缩包中的文件
    40 z.write('a.log')
    41 z.write('data.data')  # 添加单独的文件到压缩包中
    42 z.close()
    43 
    44 # 解压
    45 z = zipfile.ZipFile('laxi.zip', 'r')
    46 r = z.namelist()  # 获取压缩文件列表
    47 z.extractall()   # 没有文件名,默认解压全部文件,有文件名,则解压单独文件
    48 z.close()
    49 
    50 #处理tar包
    51 import tarfile
    52 # 压缩
    53 tar = tarfile.open('your.tar','w')
    54 tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log')
    55 tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log')
    56 tar.close()
    57 
    58 # 解压
    59 tar = tarfile.open('your.tar','r')
    60 tar.extractall()  # 可设置解压地址
    61 tar.close()

    commands模块
    commands.getoutput('shell command') # 执行shell命令,返回结果(string类型),忽略返回值
    commands.getstatusoutput('shell command') # 执行shell命令, 返回两个元素的元组tuple(status, result),status为int类型,result为string类型。返回结果包含标准输出和标准错误.
    commands.getstatus('file') # 该函数已被python丢弃,不建议使用,它返回 ls -ld file 的结果(String)

    以上执行shell命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了更丰富的功能

     

    subprocess模块

     1 import subprocess
     2 
     3 
     4 call方法:执行命令,返回状态码
     5 ret = subprocess.call(["ls", "-l"], shell=False)  # shell为False时,会把命令解析为一个字符,所以要以列表形式输入
     6 ret1 = subprocess.call("ls -l", shell=True)
     7 
     8 # check_call方法:执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
     9 subprocess.check_call(["ls", "-l"])
    10 subprocess.check_call("exit 1", shell=True)
    11 
    12 
    13 # check_output:执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
    14 subprocess.check_output(["echo", "Hello World!"])
    15 subprocess.check_output("exit 1", shell=True)
    16 
    17 
    18 # Popen方法:用于执行复杂的系统命令,程序不会阻塞,而subprocess.run是阻塞的
    19 参数:
    20 args:shell命令,可以是字符串或者序列类型(如:list,元组)
    21 bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
    22 stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
    23 preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
    24 close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
    25 所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
    26 shell:同上
    27 cwd:用于设置子进程的当前目录
    28 env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
    29 universal_newlines:不同系统的换行符不同,True -> 同意使用 
    
    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
    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
                        ),"
    ")
        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
    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
    ")
    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()

    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:本质就是字符串(内容比较特殊,是列表、字典、元组)
    http请求响应内容是字符串,如果要让python处理,需用json的loads方法。

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

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

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

     1 #处理复杂数据类型(函数等)的方法:pickle(只支持python,不支持Java(支持json))
     2 import pickle
     3 
     4 def sayhi(name):
     5     print('hello,', name)
     6 info = {
     7     'name': 'whitesky',
     8     'age': 25,
     9     'func': sayhi
    10 }
    11 
    12 f = open('test.txt', 'wb')   #pickle序列化要带b
    13 f.write(pickle.dumps(info))  #相当于 pickle._dump(info,f)
    14 
    15 
    16 #pickle反序列化
    17 
    18 f = open('test.txt', 'rb')
    19 data = pickle.loads(f.read()) # 相当于 pickle.load(f)
    20 
    21 print(data['func'])
    22 
    23 
    24 f.close()
    25 
    26 
    27 #注意:写程序序列化时要记住只dump一次,只load一次(py3中dump多次,再load时会出错,py2中正常),如果需要存储多个状态,就dump成多个文件
    View Code
     1 # -*- coding: utf-8 -*-
     2 
     3 
     4 import pickle
     5 
     6 test = [1, 2]
     7 
     8 
     9 def change(inner_list=[]):
    10     inner_list += [2, 3]
    11 
    12 change(test)
    13 
    14 pickle.dump(test, open('test_pickle_file', 'wb'))
    15 print(pickle.load(open('test_pickle_file', 'rb')))
    16 
    17 # 输出 [1, 2, 2, 3]

    XML

    格式如下:

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

    1、解析XML

     1 from xml.etree import ElementTree as ET
     2 
     3 #打开文件,读取XML内容
     4 str_xml = open('first.xml', 'r').read()
     5 
     6 #将字符串解析成xml特殊对象,root代指xml文件的根节点
     7 root = ET.XML(str_xml)
     8 
     9 #
    10 root1 = ET.XML(open('first.xml', 'r', encoding='utf-8').read())
    利用ElementTree.XML将字符串解析成xml对象
    1 from xml.etree import ElementTree as ET
    2 
    3 # 直接解析xml文件
    4 tree = ET.parse('first.xml')
    5 
    6 # 获取xml文件的根节点
    7 root = tree.getroot()
    利用ElementTree.parse将文件直接解析成xml对象
    1 xml自闭标签:http://www.cnblogs.com/ckysea/p/4627423.html 一个XML标签就是一个XML元素。 一个XML标签分为开始标签和结束标签,在开始标签和结束标签之间的文本被称为标签体。 包含标签体:<a>www.itcast.cn</a>;                  如果一个不包含标签体也不包含其他元素,那么可以将开始标签和结束标签合并,这样的标签称为自闭标签 不含标签体及其他元素:<a></a>可以简写为自闭标签:<a/>
    2 小结:
    3 tree:
    4 1.由ELementTree创建 ElementTree(xxx)
    5 2.getroot() 获取xml根节点
    6 3. write()内存中的xml写入文件中

    2、操作XML

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

     1 from xml.etree import ElementTree as ET
     2 
     3 # a.遍历XML文档的所有内容
     4 '''
     5 ############ 解析方式一:ElementTree.XML ############
     6 str_xml = open('first.xml', 'r').read()
     7 root = ET.XML(str_xml)
     8 '''
     9 ############ 解析方式二:ElementTree.parse ############
    10 tree = ET.parse('first.xml')
    11 root = tree.getroot()
    12 
    13 # print(root.tag)  # 顶层标签
    14 
    15 for second_tag in root:
    16     print(second_tag.tag, second_tag.attrib)
    17     for third_tag in second_tag:
    18         print(third_tag.tag, third_tag.text)
    19 
    20 
    21 # b.遍历XML中指定的节点
    22 # 遍历XML中所有的year节点
    23 for node in root.iter('year'):
    24     print(node.attrib, node.text)
    View Code

     b.修改节点内容

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

    tree作用总结:

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

     创建tree的方式:

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

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

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

    3、创建XML文档

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

     XML设置缩进

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

    configparser

    configparser用于处理特定格式的文件,其本质上是利用open来操作文件。(ini配置文件例子)

    [section1] # 节点
    k1 = v1    #
    k2:v2       #
    
    [section2] # 节点
    k1 = v1    #
    
    [test_ansible]
    node1 = 192.168.2.3
    ansible_ssh_port = 22
    ansible_ssh_user = gxy_ansible
    ansible_su_pass = 123456
    汉字 = 123
     1 import configparser
     2 
     3 # 获取所有节点的值
     4 config = configparser.ConfigParser()
     5 config.read('ini', encoding='utf-8') # 读到内存当中
     6 ret = config.sections()             # 获取所有节点的值
     7 print(ret)
     8 # 输出:['section1', 'section2', 'test_ansible']
     9 
    10 
    11 # 获取指定节点下所有的键值对
    12 config = configparser.ConfigParser()
    13 config.read('ini', encoding='utf-8')
    14 ret = config.items('test_ansible')   # 获取指定节点下所有的键值对
    15 print(ret)
    16 # 输出[('node1', '192.168.2.3'), ('ansible_ssh_port', '22'), ('ansible_ssh_user', 'gxy_ansible'), ('ansible_su_pass', '123456'), ('汉字', '123')]
    17 
    18 
    19 # 获取指定节点下所有的键
    20 config = configparser.ConfigParser()
    21 config.read('ini',encoding='utf-8')
    22 ret = config.options('test_ansible')  # 获取指定节点下所有的键
    23 print(ret)
    24 # 输出:['node1', 'ansible_ssh_port', 'ansible_ssh_user', 'ansible_su_pass', '汉字']
    25 
    26 
    27 # 获取指定节点下指定key的值
    28 config = configparser.ConfigParser()
    29 config.read('ini', encoding='utf-8')
    30 value = config.get('test_ansible', 'node1')  # 获取指定节点下指定key的值
    31 # v = config.getint('test_ansible', 'ansible_su_pass')   # 字符串转换为整形
    32 # v1 = config.getfloat('test_ansible', 'ansible_su_pass')
    33 # v2 = config.getboolean('test_ansible', 'node1')
    34 print(value)
    35 # 输出: 192.168.2.3
    36 
    37 
    38 # 检查、删除、添加节点
    39 config = configparser.ConfigParser()
    40 config.read('ini', encoding='utf-8')
    41 # 检查
    42 has_sec = config.has_section('test_ansible')
    43 print(has_sec)  # 输出: True
    44 # 添加节点
    45 config.add_section('test_ansible_new')
    46 config.write(open('new_ini', 'w', encoding='utf-8'))
    47 # 删除节点
    48 config.remove_section('section2')
    49 config.write(open('new_ini', 'w', encoding='utf-8'))
    50 
    51 
    52 # 检查、删除、设置指定组内的键值对
    53 config = configparser.ConfigParser()
    54 config.read('ini', encoding='utf-8')
    55 
    56 has_opt = config.has_option('test_ansible', '汉字')  # 检查,('键','值')
    57 print(has_opt)
    58 
    59 config.remove_option('section1', 'k1')
    60 config.write(open('delete_ini', 'w', encoding='utf-8'))
    61 
    62 config.set('section1', 'k2', '666666')    # 设置, 有则改,没有则新增
    63 config.write(open('set_ini', 'w', encoding='utf-8'))

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

    单文件日志

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

    日志等级:

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

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

    多文件日志

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

     1 # 定义文件
     2 file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')
     3 fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
     4 file_1_1.setFormatter(fmt)
     5 
     6 file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
     7 fmt = logging.Formatter()
     8 file_1_2.setFormatter(fmt)
     9 
    10 # 定义日志
    11 logger1 = logging.Logger('s1', level=logging.ERROR)
    12 logger1.addHandler(file_1_1)    #两个日志文件全部加入logger1文件对象中,则记录日志时,会同时写入两个文件
    13 logger1.addHandler(file_1_2)
    14 
    15 
    16 # 写日志
    17 logger1.critical('1111')
    18 
    1 # 定义文件
    2 file_2_1 = logging.FileHandler('l2_1.log', 'a')
    3 fmt = logging.Formatter()
    4 file_2_1.setFormatter(fmt)
    5 
    6 # 定义日志
    7 logger2 = logging.Logger('s2', level=logging.INFO)
    8 logger2.addHandler(file_2_1)
    日志(二)

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

    • 当使用【logger1】写日志时,会将相应的内容写入 l1_1.log 和 l1_2.log 文件中
    • 当使用【logger2】写日志时,会将相应的内容写入 l2_1.log 文件中
      1 import logging
      2   
      3 # 日志配置:
      4 logging.basicConfig(filename='log.log',
      5                     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
      6                     datefmt='%Y-%m-%d %H:%M:%S %p',
      7                     level=10)
      8  
      9 # 日志记录的方法: 
     10 logging.debug('debug')        # 内部调用的logging.log, 相当于logging.log(10,'debug')
     11 logging.info('info')
     12 logging.warning('warning')  # 建议用这
     13 logging.error('error')
     14 logging.critical('critical')
     15 logging.log(10,'log')
     16 
     17 
     18 
     19 
     20 
     21 
     22 
     23 # 定义文件
     24 #创建第一个文件对象(FileHandler方法)
     25 file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')            # 定义文件名为:l1_1.log
     26 fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")    # logging.Formatter格式化处理
     27 file_1_1.setFormatter(fmt)
     28 
     29 #创建第二个文件对象
     30 file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')
     31 fmt = logging.Formatter()
     32 file_1_2.setFormatter(fmt)
     33 
     34 
     35 # 定义日志
     36 #创建写日志的对象
     37 logger1 = logging.Logger('s1', level=logging.ERROR)  # s1会写到logging.Formatter的%(name)处
     38 logger1.addHandler(file_1_1)                        # 将文件对象加入写日志的对象中,用于写日志
     39 logger1.addHandler(file_1_2)
     40 
     41 
     42 # 写日志
     43 logger1.critical('1111')                    # 关联了上面两个文件(file_1_1和file_1_2),所以一条日志信息会同时写入上面两个文件中
     44 
     45 
     46 
     47 
     48 
     49 # 实战:
     50 同时定义两个日志文件,
     51 # 定义文件
     52 file_1_1 = logging.FileHandler('run.log', 'a', encoding='utf-8')    # 定义文件名为:run.log
     53 fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
     54 file_1_1.setFormatter(fmt)
     55 
     56 # 定义日志
     57 logger1 = logging.Logger('s1', level=logging.ERROR)
     58 logger1.addHandler(file_1_1)
     59 
     60 # 写日志
     61 logger1.critical('1111')
     62 
     63 
     64 
     65 # 定义文件
     66 file_1_1 = logging.FileHandler('error.log', 'a', encoding='utf-8')    # 定义文件名为:error.log
     67 fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
     68 file_1_1.setFormatter(fmt)
     69 
     70 # 定义日志
     71 logger1 = logging.Logger('s1', level=logging.ERROR)
     72 logger1.addHandler(file_1_1)
     73 
     74 # 写日志
     75 logger1.critical('1111')
     76 
     77 
     78 CMDB中的应用:
     79     def initialize_run_log(self):
     80         self.check_path_exist(self.run_log_file)
     81         file_1_1 = logging.FileHandler(self.run_log_file, 'a', encoding='utf-8')    # 文件对象
     82         fmt = logging.Formatter(fmt="%(asctime)s - %(levelname)s :  %(message)s")    # 设置日志格式
     83         file_1_1.setFormatter(fmt)                                                    # 设置日志格式
     84         logger1 = logging.Logger('run_log', level=logging.INFO)
     85         logger1.addHandler(file_1_1)
     86         self.run_logger = logger1
     87 
     88     def initialize_error_log(self):
     89         self.check_path_exist(self.error_log_file)
     90         file_1_1 = logging.FileHandler(self.error_log_file, 'a', encoding='utf-8')
     91         fmt = logging.Formatter(fmt="%(asctime)s  - %(levelname)s :  %(message)s")
     92         file_1_1.setFormatter(fmt)
     93         logger1 = logging.Logger('run_log', level=logging.ERROR)
     94         logger1.addHandler(file_1_1)
     95         self.error_logger = logger1
     96         
     97     def log(self, message, mode=True):
     98         """
     99         写入日志
    100         :param message: 日志信息
    101         :param mode: True表示运行信息,False表示错误信息
    102         :return:
    103         """
    104         if mode:
    105             self.run_logger.info(message)
    106         else:
    107             self.error_logger.error(message)
    logging方法实践

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

     

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

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

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

    traceback捕获并打印异常:

     1 异常处理是日常操作了,但是有时候不能只能打印我们处理的结果,还需要将我们的异常打印出来,这样更直观的显示错误
     2 下面来介绍traceback模块来进行处理
     3     try:
     4         1/0
     5     except Exception, e:
     6         print e
     7 输出结果是integer division or modulo by zero,只知道是报了这个错,但是却不知道在哪个文件哪个函数哪一行报的错。
     8 
     9 使用traceback
    10     try:
    11         1/0
    12     except Exception, e:
    13         traceback.print_exc()
    14 Traceback (most recent call last):
    15 
    16         File "test_traceback.py", line 3, in <module>
    17 
    18            1/0
    19 
    20 ZeroDivisionError: integer division or modulo by zero  # 这样非常直观有利于调试。
    21 
    22 # traceback.print_exc()跟traceback.format_exc()有什么区别呢?
    23 print_exc()则直接给打印出来;
    24 format_exc()返回字符串;
    25 即traceback.print_exc()与print traceback.format_exc()效果是一样的。
    26 print_exc()还可以接受file参数直接写入到一个文件。
    27 比如:
    28 traceback.print_exc(file=open('tb.txt','w+')) # 写入到tb.txt文件去。        
     1 也可以使用logger.exception(msg,_args),它等价于logger.error(msg,exc_info = True,_args),
     2 
     3  4 
     5 logger.error("Faild to open sklearn.txt from logger.error",exc_info = True)
     6 替换为,
     7 
     8 logger.exception("Failed to open sklearn.txt from logger.exception")
     9 控制台和日志文件log.txt中输出,
    10 
    11 Start print log
    12 Something maybe fail.
    13 Failed to open sklearn.txt from logger.exception
    14 Traceback (most recent call last):
    15   File "G: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')。
    import和__import__()
     1 s.rsplit()和s.split()区别是什么啊
     2 
     3 一个从左开始,一个从右开始。
     4 如果是这样没有区别:
     5 >>> s = 'asd dfdf ff'
     6 >>> s.split()
     7 ['asd', 'dfdf', 'ff']
     8 >>> s.rsplit()
     9 ['asd', 'dfdf', 'ff']
    10 
    11 这样就看出不同了。
    12 >>> s.split(' ',1)
    13 ['asd', 'dfdf ff']
    14 >>> s.rsplit(' ',1)
    15 ['asd dfdf', 'ff']
    s.rsplit()和s.split()区别是什么啊

    random模块:

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

    importlib

    #环境:python 3.6
    
    
    # 文件结构
    
    ├── clazz
    │   ├── __init__.py
    │   ├── a.py
    │   └── b.py
    └── main.py
    
    
    
    # a.py 的代码
    
    def show():
        print("show A")
        
        
    # b.py 的代码
    
    def show():
        print("show B")    
        
        
        
    从main中导入clazz包中的a 和b 模块
    main.py
    
    import importlib
    
    # 绝对导入
    a = importlib.import_module("clazz.a")
    a.show()
    # show A
    
    # 相对导入
    b = importlib.import_module(".b", "clazz")
    b.show()
    # show B
    
    注意,相对导入有个一点., 类似路径
    unix时间戳:
    # 10位时间戳获取方法:
    
    >>> import time
    >>> t = time.time()
    >>> print t
    1436428326.76
    >>> print int(t)
    1436428326
    >>>
    
    
    # 13位时间戳获取方法:
    1)默认情况下python的时间戳是以秒为单位输出的float
    
    >>> import time
    >>> time.time()
    1436428275.207596
    
    
    # 通过把秒转换毫秒的方法获得13位的时间戳:
    import time
    millis = int(round(time.time() * 1000))      # round()四舍五入函数。
    print millis
    
    
    
    
    import time
     
    current_milli_time = lambda: int(round(time.time() * 1000))
    Then:
    >>> current_milli_time()
    1378761833768
    #!/usr/bin/env python3
    # -*-coding:utf-8 -*-
    # xiaoe直播监控脚本
    __author__ = 'budyu'
    __date__ = '2019/4/4 21:34'
    
    import requests
    import json
    import sys
    import logging
    import datetime
    
    # logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',datefmt='%Y-%m-%d %H:%M:%S %p',level=10)
    
    # file_handler = logging.FileHandler('/var/log/alive_mon.log', 'a', encoding='utf-8')
    # fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
    # file_handler.setFormatter(fmt)
    
    # logger1 = logging.Logger('alive_mon_log', level=logging.DEBUG)
    # logger1.addHandler(file_handler)
    
    start_time = ''
    stop_time = ''
    
    now = datetime.datetime.now()
    one_min_delta = now - datetime.timedelta(minutes=1)
    # now_time = one_min_delta.strftime('%Y-%m-%d %H:%M:%S')
    now_time_minute = one_min_delta.strftime('%M')
    result = int(now_time_minute) % 5
    # print(result)
    # print(not result)
    #  取0,5,10,15,20...分钟
    if not result:
        stop_time = one_min_delta.strftime('%Y-%m-%d %H:%M:%S')
        stop_time = datetime.datetime.strptime(stop_time, "%Y-%m-%d %H:%M:%S")
        # print(stop_time, '----------------------------')
    else:
        stop_time_min = int(now_time_minute) - result
        stop_time = one_min_delta.strftime('%Y-%m-%d %H:{}:%S').format(str(stop_time_min).zfill(2))
        stop_time = datetime.datetime.strptime(stop_time, "%Y-%m-%d %H:%M:%S")
        # print(stop_time, '||||||||||||||||||||||||||||')
    
    start_time = stop_time - datetime.timedelta(minutes=5)
    # print(start_time, 'start_time @@@@@@@@@@@@@@@@@@@@@@')
    
    alive_panel_url = 'http://134.175.37.247:1224/alive_panel'
    online_user_url = 'http://134.175.37.247:1224/alive_online_users'
    
    payload = {'start_at': start_time, 'stop_at': stop_time}
    # payload = {'start_at': '2019-04-10 17:0:20', 'stop_at': '2019-04-10 17:0:00'}
    # print(payload)
    panel_ret = requests.get(
        url=alive_panel_url,
        # params=payload
    )
    online_user_ret = requests.get(
        url=online_user_url,
        params=payload
    )
    
    # print(panel_ret.text, 'panel_ret -----------')
    # print(online_user_ret.text, ' online_user_ret  ----------------')
    
    response_panel = json.loads(panel_ret.text)
    response_online_user = json.loads(online_user_ret.text)
    # print(response_panel, '======================')
    # print(response_online_user, '======================')
    
    if response_panel['code'] == 0:
        try:
            if sys.argv[1] == 'avgInterTime':
                avgInterTime = response_panel.get('data')['avgInterTime']
                print(int(avgInterTime))
            elif sys.argv[1] == 'interFailRate':
                interFailRate = response_panel.get('data')['interFailRate']
                print(interFailRate)
            elif sys.argv[1] == 'interReqCount':
                interReqCount = response_panel.get('data')['interReqCount']
                print(int(interReqCount))
            elif response_online_user['code'] == 0 and sys.argv[1] == 'onlineUsers':
                onlineUsers = response_online_user.get('data')['onlineUsers']
                print(int(onlineUsers))
            else:
                print(
                    "response_online_user failed! (Usage: python {0} avgInterTime|interFailRate|interReqCount|onlineUsers)".format(
                        sys.argv[0]))
        except Exception as e:
            #    logger1.critical('may be get wrong argument !')
            print("reponse error! INFO:{0}".format(e))
    
    elif response_panel['code'] == 12:
        # logger1.critical('no data repsonse from {0}'.format(requests_url))
        print('no data')
    elif response_panel['code'] == 8:
        # logger1.critical('request timeout from {0}'.format(requests_url))
        print('request time error')
    经常使用的时间方法
    
    
    1.得到当前时间
    使用time模块,首先得到当前的时间戳
    In [42]: time.time()
    Out[42]: 1408066927.208922
    
    将时间戳转换为时间元组 struct_time
    In [43]: time.localtime(time.time())
    Out[43]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=9, tm_min=42, tm_sec=20, tm_wday=4, tm_yday=227, tm_isdst=0)
    
    格式化输出想要的时间
    In [44]: time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
    Out[44]: '2014-08-15 09:43:04'
    
    接上文,不加参数时,默认就是输出当前的时间
    In [48]: time.strftime('%Y-%m-%d %H:%M:%S')
    Out[48]: '2014-08-15 09:46:53’
    
    当然也可以透过datetime模块来实现,如下:
    In [68]: t = time.time()
    In [69]: datetime.datetime.fromtimestamp(t).strftime('%Y-%m-%d %H:%M:%S')
    Out[69]: '2014-08-15 10:04:51’
    
    同时,也可以只使用datetime模块
    In [46]: datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    Out[46]: '2014-08-15 09:45:27’
    In [47]: datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S')
    Out[47]: '2014-08-15 09:46:10'
    
    2.获取时间差,计算程序的执行时间等:
    使用time模块:
    In [75]: def t():
       ....:     start = time.time()
       ....:     time.sleep(10)
       ....:     end = time.time()
       ....:     print end - start
       ....:
    
    In [76]: t()
    10.0014948845
    
    使用datetime模块:
    In [49]: starttime = datetime.datetime.now()
    In [50]: endtime = datetime.datetime.now()
    In [51]: print (endtime - starttime).seconds
    
    
    2.计算昨天的日期(发散思维,计算其他日期相加、相减等):
    
    In [52]: d1 = datetime.datetime.now()
    In [53]: d2 = d1 - datetime.timedelta(days=1)
    In [54]: d1
    Out[54]: datetime.datetime(2014, 8, 15, 9, 54, 10, 68665)
    In [55]: d2
    Out[55]: datetime.datetime(2014, 8, 14, 9, 54, 10, 68665)
    
    
    
    3.时间元组 struct_time转化为时间戳
    In [56]: datetime.datetime.now()
    Out[56]: datetime.datetime(2014, 8, 15, 9, 57, 52, 779893)
    
    In [57]: datetime.datetime.now().timetuple()
    Out[57]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=9, tm_min=58, tm_sec=12, tm_wday=4, tm_yday=227, tm_isdst=-1)
    
    In [58]: time.mktime(datetime.datetime.now().timetuple())
    Out[58]: 1408067904.0
    
    
    
    4.strptime也挺有用的,将时间字符串转换为时间元组struct_time
    In [73]: time.strftime('%Y-%m-%d %H:%M:%S')
    Out[73]: '2014-08-15 10:27:36'
    
    In [74]: time.strptime('2014-08-15 10:27:36','%Y-%m-%d %H:%M:%S')
    Out[74]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=10, tm_min=27, tm_sec=36, tm_wday=4, tm_yday=227, tm_isdst=-1)
    
    
    
    
    
    
    二:time和datetime模块常用方法简介
    
    表示时间的两种方式:
    
    1. 时间戳(相对于1970.1.1 00:00:00以秒计算的偏移量),时间戳是惟一的
    2. 时间元组 即(struct_time),共有九个元素,分别表示,同一个时间戳的struct_time会因为时区不同而不同
    
    
    time 模块常用方法小记:
    1.time.clock()
    
    这个需要注意,在不同的系统上含义不同。在UNIX系统上,它返回的是“进程时间”,它是用秒表示的浮点数(时间 戳)。而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行时间。(实际上是以WIN32 上QueryPerformanceCounter()为基础,它比毫秒表示更为精确)
    
    budong@budongdeMacBook-Pro:/tmp$ cat clock.py
    #!/usr/bin/env python
    import time
    if __name__ == '__main__':
        time.sleep(1)
        print "clock1:%s" % time.clock()
        time.sleep(1)
        print "clock2:%s" % time.clock()
        time.sleep(1)
        print "clock3:%s" % time.clock()
    
    运行脚本:
    budong@budongdeMacBook-Pro:/tmp$ ./clock.py
    clock1:0.059173
    clock2:0.059299
    clock3:0.059416
    
    
    
    2.time.sleep(secs)
    
    线程推迟指定的时间运行
    适合放在脚本里,定时sleep一会然后继续干啥
    
    In [138]: while True:
       .....:     time.sleep(3)
       .....:     print time.strftime('%H:%M:%S')
       .....:
    17:21:35
    17:21:38
    17:21:41
    17:21:44
    ……
    
    
    
    3.time.localtime([secs])
    
    将一个时间戳转换成一个当前时区的struct_time,如果seconds参数未输入,则以当前时间为转换标准
    未提供secs参数时,按当前时间为准
    In [141]: time.localtime()
    Out[141]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=14, tm_hour=17, tm_min=23, tm_sec=48, tm_wday=3, tm_yday=226, tm_isdst=0)
    
    提供secs为当前时间戳时
    In [142]: time.time()
    Out[142]: 1408008232.217969
    In [143]: time.localtime(time.time())
    Out[143]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=14, tm_hour=17, tm_min=24, tm_sec=2, tm_wday=3, tm_yday=226, tm_isdst=0)
    
    
    
    4.time.strftime(format[, t])
    
    将指定的struct_time(默认为当前时间),根据指定的格式化字符串输出
    t未指定,传入time.localtime()作为默认参数:
    In [156]: time.strftime('%Y-%m-%d %H:%M:%S')
    Out[156]: '2014-08-14 17:28:16’
    
    指定t为time.localtime(1407945600.0)时:
    In [157]: time.localtime(1407945600.0)
    Out[157]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=14, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=226, tm_isdst=0)
    
    In [158]: time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(1407945600.0))
    Out[158]: '2014-08-14 00:00:00’
    
    
    5.time.time()
    
    返回当前时间的时间戳
    In [161]: time.time()
    Out[161]: 1408008711.730218
    
    
    6.time.mktime(t)
    
    将一个struct_time转换为时间戳,如下time.localtime接收一个时间戳返回一个struct_time,而time.mktime接收一个struct_time,返回一个时间戳
    In [159]: time.localtime(1407945600.0)
    Out[159]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=14, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=226, tm_isdst=0)
    In [160]: time.mktime(time.localtime(1407945600.0))
    Out[160]: 1407945600.0
    
    残阳似血的博客:<http://qinxuye.me/article/details-about-time-module-in-python/> 
    
    官方time模块:<http://python.me/library/time.html#module-time>
    
    
    
    ##datetime 模块常用方法小记
    
    datetime模块常用的主要有下面这四个类:
    
    1. datetime.date: 是指年月日构成的日期(相当于日历)
    2. datetime.time: 是指时分秒微秒构成的一天24小时中的具体时间(相当于手表)
    3. datetime.datetime: 上面两个合在一起,既包含时间又包含日期
    4. datetime.timedelta: 时间间隔对象(timedelta)。一个时间点(datetime)加上一个时间间隔(timedelta)可以得到一个新的时间点(datetime)。比如今天的上午3点加上5个小时得到今天的上午8点。同理,两个时间点相减会得到一个时间间隔。
    
    
    1.datetime.date 类
    
    1.新建一个date对象,日期为今天,既可以直接调用datetime.date.today(),也可以直接向datetime.date()传值,如下:
    In [4]: today = datetime.date.today()
    In [5]: today
    Out[5]: datetime.date(2014, 8, 15)
    In [6]: t = datetime.date(2014,8,15)
    In [7]: t
    Out[7]: datetime.date(2014, 8, 15)
    
    2.datetime.date.strftime(format) 格式化为需要的时间,如常用的 “年-月-日 小时:分钟:秒” 格式
    In [8]: today.strftime('%Y-%m-%d %H:%M:%S')
    Out[8]: '2014-08-15 00:00:00’
    date对象中小时、分钟、秒默认都是0,纪元年的那个时间
    
    3.datetime.date.timple() 转成struct_time格式,这样传递给time.mktime(t)  后,直接转成时间戳格式
    In [9]: today.timetuple()
    Out[9]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=227, tm_isdst=-1)
    In [10]: time.mktime(today.timetuple())
    Out[10]: 1408032000.0
    
    4.datetime.date.replace(year, month, day)  返回一个替换后的date对象
    In [11]: today.replace(year=2013)
    Out[11]: datetime.date(2013, 8, 15)
    
    5.datetime.date.fromtimestamp(timestamp) 将时间戳转化为date对象
    In [12]: datetime.date.fromtimestamp(1408058729)
    Out[12]: datetime.date(2014, 8, 15)
    
    
    
    2.datetime.time 类
    
    1.新建一个time对象
    In [15]: t
    Out[15]: datetime.time(8, 45, 20)
    
    2.datetime.time.(format)格式化输出
    In [16]: t.strftime('%Y-%m-%d %H:%M:%S')
    Out[16]: '1900-01-01 08:45:20’
    time对应的年、月、日为1900、01、01,纪元年的那个时间
    
    3.datetime.time.replace([hour[, minute[, second[, microsecond[, tzinfo]]]]])  返回一个替换后的time对象
    In [17]: t.replace(hour=9)
    Out[17]: datetime.time(9, 45, 20)
    
    
    3.datetime.datetime类
    
    其实和date的那些方法差不多了,大概看以下,简单说说
    1.新建一个datetime对象,日期为今天,既可以直接调用datetime.datetime.today(),也可以直接向datetime.datetime()传值,如下:
    In [21]: d1 = datetime.datetime.today()
    In [22]: d1
    Out[22]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
    In [23]: d2 = datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
    In [24]: d2
    Out[24]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
    
    2.datetime.datetime.now([tz]) 当不指定时区时,和datetime.datetime.today()是一样的结果,如下
    In [25]: datetime.datetime.now()
    Out[25]: datetime.datetime(2014, 8, 15, 8, 14, 50, 738672)
    
    3..datetime.datetime.strftime(format) 格式化为需要的时间,如常用的 “年-月-日 小时:分钟:秒” 格式
    In [27]: d1
    Out[27]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
    In [28]: d1.strftime('%Y-%m-%d %H:%M:%S')
    Out[28]: '2014-08-15 08:12:34’
    
    4.datetime.datetime.timple() 转成struct_time格式,这样传递给time.mktime(t)  后,直接转成时间戳格式
    In [29]: d1
    Out[29]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
    In [30]: d1.timetuple()
    Out[30]: time.struct_time(tm_year=2014, tm_mon=8, tm_mday=15, tm_hour=8, tm_min=12, tm_sec=34, tm_wday=4, tm_yday=227, tm_isdst=-1)
    In [31]: time.mktime(d1.timetuple())
    Out[31]: 1408061554.0
    
    5.datetime.datetime.replace(year, month, day)  返回一个替换后的date对象
    In [32]: d1
    Out[32]: datetime.datetime(2014, 8, 15, 8, 12, 34, 790945)
    In [33]: d1.replace(year=2000)
    Out[33]: datetime.datetime(2000, 8, 15, 8, 12, 34, 790945)
    
    6.datetime.datetime.fromtimestamp(timestamp) 将时间戳转化为datetime对象
    In [34]: time.time()
    Out[34]: 1408061894.081552
    In [35]: datetime.datetime.fromtimestamp(1408061894)
    Out[35]: datetime.datetime(2014, 8, 15, 8, 18, 14)
    
    
    4.datetime.timedelta类
    主要做时间的加减法用,如下:
    In [78]: today = datetime.datetime.today()
    In [79]: yesterday = today - datetime.timedelta(days=1)
    In [80]: yesterday
    Out[80]: datetime.datetime(2014, 8, 14, 15, 8, 25, 783471)
    In [81]: today
    Out[81]: datetime.datetime(2014, 8, 15, 15, 8, 25, 783471)
    
    
    当前时间
    
    datetime.datetime.now() 
     
    
    时间间隔
    
    datetime.timedelta(参数=数值)  #参数:weeks,days,hours,minutes,seconds,microseconds,milliseconds
    
    
    import datetime
    
    nowtime = datetime.datetime.now()
    print(nowtime) #当前时间
    
    print(datetime.datetime.now() - datetime.timedelta(days=1)) #1天前 默认格式2019-02-11 13:27:16.231381
    print(datetime.datetime.now() + datetime.timedelta(days=1)) #1天后
    
    print((datetime.datetime.now() - datetime.timedelta(weeks=2)).strftime("%Y-%m-%d %H:%M:%S")) #两周前
    print((datetime.datetime.now() + datetime.timedelta(weeks=2)).strftime("%Y-%m-%d %H:%M:%S")) #两周后
    
    print((datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S")) #1天前
    print((datetime.datetime.now() + datetime.timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S"))#1天后
    
    print((datetime.datetime.now() - datetime.timedelta(hours=2)).strftime("%Y-%m-%d %H:%M:%S")) #2小时前
    print((datetime.datetime.now() + datetime.timedelta(hours=2)).strftime("%Y-%m-%d %H:%M:%S")) #2小时后
    
    print((datetime.datetime.now() - datetime.timedelta(minutes=30)).strftime("%Y-%m-%d %H:%M:%S"))# 30分钟前
    print((datetime.datetime.now() + datetime.timedelta(minutes=30)).strftime("%Y-%m-%d %H:%M:%S")) #30分钟后
    
    print((datetime.datetime.now() - datetime.timedelta(seconds=10)).strftime("%Y-%m-%d %H:%M:%S")) #10秒前
    print((datetime.datetime.now() + datetime.timedelta(seconds=10)).strftime("%Y-%m-%d %H:%M:%S")) #10秒后
    常用事件方法

    python datetime time 时间模块

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

    日期、时间戳互转:

    # 引入模块
    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)

    重要:python第三方库 - dateutil:

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

  • 相关阅读:
    上传文件插件-bootstrap-fileinput
    js【jquery】
    html
    CSS3中的vh、vw及其应用场景
    element,点击查看,实现tab切换:
    js 遍历tree的一个例子(全遍历),更复杂的功能
    js 遍历tree的一个例子(全遍历)
    js 遍历tree的一个例子
    您的连接不是私密连接
    Es6中Map对象和Set对象的介绍及应用
  • 原文地址:https://www.cnblogs.com/yum777/p/6768739.html
Copyright © 2011-2022 走看看