• Python高手之路【七】python基础之模块


    本节大纲


    1. 模块介绍
    2. time &datetime模块
    3. random
    4. os
    5. sys
    6. shutil
    7. json & picle
    8. shelve
    9. xml处理
    10. yaml处理
    11. configparser
    12. hashlib
    13. subprocess
    14. logging模块
    15. re正则表达式

    1:模块介绍

    模块,用一砣代码实现了某个功能的代码集合。 

    类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。

    如:os 是系统相关的模块;file是文件操作相关的模块

    模块分为三种:

    • 自定义模块
    • 内置标准模块(又称标准库)
    • 开源模块

    模块导入的三种方式:

    方法一:

    import modname 

    用import语句导入模块,就在当前的名称空间(namespace)建立了一个到该模块的引用.这种引用必须使用全称,也就是说,当使用在被导入模块中定义的函数时,必须包含模块的名字。所以不能只使用 funcname,而应该使用 modname.funcname

    方法二:

    from modname import funcname   
    from modname import fa, fb, fc 
    from modname import * 

            与第1种方法的区别:funcname 被直接导入到本地名字空间去了,所以它可以直接使用,而不需要加上模块名的限定* 表示,该模块的所有公共对象(public objects)都被导入到 当前的名称空间,也就是任何只要不是以”_”开始的东西都会被导入。 
           modname没有被定义,所以modname.funcname这种方式不起作用。并且,如果funcname如果已经被定义,它会被新版本(该导入模块中的版本)所替代。如果funcname被改成指向其他对象,modname不能不会觉察到。 
    建议:

    1. 如果你要经常访问模块的属性和方法,且不想一遍又一遍地敲入模块名,使用 from module import 
    2. 如果你想要有选择地导入某些属性和方法,而不想要其它的,使用 from module import 
    3. 如果模块包含的属性和方法与你的某个模块同名,你必须使用import module来避免名字冲突 
    4. 尽量少用 from module import * ,因为判定一个特殊的函数或属性是从哪来的有些困难,并且会造成调试和重构都更困难。

    2:time & datetime模块

     1 #_*_coding:utf-8_*_
     2 __author__ = 'Alex Li'
     3 
     4 import time
     5 
     6 
     7 # print(time.clock()) #返回处理器时间,3.3开始已废弃 , 改成了time.process_time()测量处理器运算时间,不包括sleep时间,不稳定,mac上测不出来
     8 # print(time.altzone)  #返回与utc时间的时间差,以秒计算
     9 # print(time.asctime()) #返回时间格式"Fri Aug 19 11:14:16 2016",
    10 # print(time.localtime()) #返回本地时间 的struct time对象格式
    11 # print(time.gmtime(time.time()-800000)) #返回utc时间的struc时间对象格式
    12 
    13 # print(time.asctime(time.localtime())) #返回时间格式"Fri Aug 19 11:14:16 2016",
    14 #print(time.ctime()) #返回Fri Aug 19 12:38:29 2016 格式, 同上
    15 
    16 
    17 
    18 # 日期字符串 转成  时间戳
    19 # string_2_struct = time.strptime("2016/05/22","%Y/%m/%d") #将 日期字符串 转成 struct时间对象格式
    20 # print(string_2_struct)
    21 # #
    22 # struct_2_stamp = time.mktime(string_2_struct) #将struct时间对象转成时间戳
    23 # print(struct_2_stamp)
    24 
    25 
    26 
    27 #将时间戳转为字符串格式
    28 # print(time.gmtime(time.time()-86640)) #将utc时间戳转换成struct_time格式
    29 # print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将utc struct_time格式转成指定的字符串格式
    30 
    31 
    32 
    33 
    34 
    35 #时间加减
    36 import datetime
    37 
    38 # print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925
    39 #print(datetime.date.fromtimestamp(time.time()) )  # 时间戳直接转成日期格式 2016-08-19
    40 # print(datetime.datetime.now() )
    41 # print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
    42 # print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
    43 # print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
    44 # print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分
    45 
    46 
    47 #
    48 # c_time  = datetime.datetime.now()
    49 # print(c_time.replace(minute=3,hour=2)) #时间替换

    3:random

    import random
     
    print(random.random())
    print(random.randint(1, 2))
    print(random.randrange(1, 10))

    4:OS模块

    用于提供系统级别的操作:

    os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径
    os.chdir("dirname")         改变当前脚本工作目录;相当于shell下cd
    os.curdir                   返回当前目录: ('.')
    os.pardir                   获取当前目录的父目录字符串名:('..')
    os.makedirs('dir1/dir2')    可生成多层递归目录
    os.removedirs('dirname1')   若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    os.mkdir('dirname')         生成单级目录;相当于shell中mkdir dirname
    os.rmdir('dirname')         删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
    os.listdir('dirname')       列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    os.remove()                 删除一个文件
    os.rename("oldname","new")  重命名文件/目录
    os.stat('path/filename')    获取文件/目录信息
    os.sep                      操作系统特定的路径分隔符,win下为"\",Linux下为"/"
    os.linesep                  当前平台使用的行终止符,win下为"	
    ",Linux下为"
    "
    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所指向的文件或者目录的最后修改时间

    5:sys模块

    sys模块用于提供对python解释器相关的操作:

    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]

    练习题:

    1:读写用户的输入,根据用户输入,创建一个相应的目录

    import sys,os
    print(sys.argv)
    os.mkdir(sys.argv[1])

    在命令行下执行:

    D:PythonPython35-32>python e:/wwwroot/py
    ['e:/wwwroot/python/index.py', 'testdir']

    执行完毕,在D:PythonPython35-32目录下就多了一个testdir的目录

    2:自己写一个简单的脚本,可以在任何路径导入

    3:进度条,带百分比

    1 import sys,time
    2 for i in range(31):
    3     sys.stdout.write('
    ')
    4     sys.stdout.write("%s%% |%s" % (int(i/30*100),int(i/30*100)*'*'))
    5     sys.stdout.flush()
    6     time.sleep(0.1)

     如何添加sys.path路径:

    import sys
    sys.path.append("D:")#这里写需要添加的路径
    for i in sys.path:
        print(i)

    6:shuntil

    高级的 文件、文件夹、压缩包 处理模块

    shutil.copyfileobj(fsrc, fdst[, length]):将文件内容拷贝到另一个文件中

    1 import shutil
    2  
    3 shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))

    shutil.copyfile(src, dst):拷贝文件

    shutil.copyfile('f1.log', 'f2.log')

    shutil.copymode(src, dst):仅拷贝权限。内容、组、用户均不变

    shutil.copymode('f1.log', 'f2.log')

    shutil.copystat(src, dst):仅拷贝状态的信息,包括:mode bits, atime, mtime, flags

    shutil.copystat('f1.log', 'f2.log')

    shutil.copy(src, dst):拷贝文件和权限

    import shutil
     
    shutil.copy('f1.log', 'f2.log')

    shutil.copy2(src, dst):拷贝文件和状态信息

    import shutil
     
    shutil.copy2('f1.log', 'f2.log')

    shutil.ignore_patterns(*patterns)
    shutil.copytree(src, dst, symlinks=False, ignore=None)
    递归的去拷贝文件夹

    import shutil
     
    shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))

     

    import shutil
    
    shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))

     

    shutil.rmtree(path[, ignore_errors[, onerror]])
    递归的去删除文件

    import shutil
     
    shutil.rmtree('folder1')

    shutil.move(src, dst)
    递归的去移动文件,它类似mv命令,其实就是重命名。

    import shutil
     
    shutil.move('folder1', 'folder3')

    shutil.make_archive(base_name, format,...)

    创建压缩包并返回文件路径,例如:zip、tar

    创建压缩包并返回文件路径,例如:zip、tar

    • base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    • 如:www =>保存至当前路径
    • 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
    • format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    • root_dir: 要压缩的文件夹路径(默认当前目录)
    • owner: 用户,默认当前用户
    • group: 组,默认当前组
    • logger: 用于记录日志,通常是logging.Logger对象
    1 #将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录
    2 import shutil
    3 ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
    4   
    5   
    6 #将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录
    7 import shutil
    8 ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')

    shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:

     1 import zipfile
     2 
     3 # 压缩
     4 z = zipfile.ZipFile('laxi.zip', 'w')
     5 z.write('a.log')
     6 z.write('data.data')
     7 z.close()
     8 
     9 # 解压
    10 z = zipfile.ZipFile('laxi.zip', 'r')
    11 z.extractall()
    12 z.close()
    13 
    14 zipfile解压缩
    ZIPfile解压缩
     1 import tarfile
     2 
     3 # 压缩
     4 tar = tarfile.open('your.tar','w')
     5 tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log')
     6 tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log')
     7 tar.close()
     8 
     9 # 解压
    10 tar = tarfile.open('your.tar','r')
    11 tar.extractall()  # 可设置解压地址
    12 tar.close()
    13 
    14 tarfile解压缩
    tarfile解压缩

    7:json & pickle 模块

    用于序列化的两个模块

    • json,用于字符串 和 python数据类型间进行转换
    • pickle,用于python特有的类型 和 python的数据类型间进行转换

    Json模块提供了四个功能:dumps、dump、loads、load

    pickle模块提供了四个功能:dumps、dump、loads、load

    pickle模块的dumps,loads演示:

    假如现在有一个字典弄的数据,内容如下:

    accounts = {
        1000:{
            'name':'poe',
            'password':'123456',
            'email':'ginvip@qq.com',
            'balance':15000,
            'phone':13888888888,
            'back_acc':{'ICBC':62202,'CBC':52202,'ABC':42202}
        },
        1001:{
            'name':'jet',
            'password':'654321',
            'email':'jet@qq.com',
            'balance':150,
            'phone':13888888888,
            'back_acc':{'ICBC':62202}
        }
    }

    那么如何将这个字典型的数据持久化保存到硬盘里呢?由于文件的写入只允许保存字符串,所以一般的方法无法将该字典型数据保存到硬盘里,这里就需要用到pickle模块的dumps与loads功能

     1 import pickle
     2 accounts = {
     3     1000:{
     4         'name':'poe',
     5         'password':'123456',
     6         'email':'ginvip@qq.com',
     7         'balance':15000,
     8         'phone':13888888888,
     9         'back_acc':{'ICBC':62202,'CBC':52202,'ABC':42202}
    10     },
    11     1001:{
    12         'name':'jet',
    13         'password':'654321',
    14         'email':'jet@qq.com',
    15         'balance':150,
    16         'phone':13888888888,
    17         'back_acc':{'ICBC':62202}
    18     }
    19 }
    20 f = open('account.db','wb')
    21 f.write(pickle.dumps(accounts))
    22 f.close()
    account.py

    数据保存后,那么如果需要重写,该怎么办呢?

     1 import pickle
     2 acc_file_name = "account.db"
     3 account_file = open(acc_file_name,'rb')
     4 # print(pickle.loads(account_file.read()))
     5 account_dic = pickle.loads(account_file.read())
     6 account_file.close()
     7 account_dic[1000]['balance'] -= 500
     8 f = open(acc_file_name,'wb')
     9 f.write(pickle.dumps(account_dic))
    10 f.close()
    11 print(account_dic)
    shopping.py

    验证数据是否写入成功:

    import pickle
    f = open("account.db",'rb')
    
    account_db = pickle.loads(f.read())
    print(account_db)
    check.py

     

     1 import json
     2 s = '{"key1":"value1","key2":"value2"}'  # ==> 用json模块将字符串转化成其他数据类型,字符串里出现引号必须用双引号
     3 ret = json.loads(s)  # ==> loads 由字符串转其他数据类型
     4 print(ret,type(ret))
     5 
     6 ret = json.load(open('ethan.txt','r')) # ==> 将文档(内部是字符串格式)转换成python的其他数据类型
     7 print(ret,type(ret))  # ==> 文档里是字典样式的字符串
     8 
     9 l = '[11,22,3,56,75]'
    10 result =json.loads(l)
    11 print(result,type(result))
    12 # 总结:
    13 # json.loads()用于将形似字典、列表、元组的字符串,转换成字典、列表、元组
    14 # json.load() 用于将文档(内容是形似字典、列表、元组的字符串)转换成字典、列表、元组
    15 
    16 di = {"key1":"value1","key2":"value2"}
    17 ret = json.dumps(di) # ==> 将字典、列表、元组 转换成字符串格式
    18 print(ret,type(ret))
    19 
    20 json.dump(di,open('ethan.txt','a+'))  # ==> 将字典、元组、列表转换成字符串格式并写入文档
    21 
    22 import pickle
    23 
    24 d = {'name':'ethan','age':28}
    25 ret = pickle.dumps(d) # ==> pickle将字典、元组、列表转换成二进制
    26 print(ret,type(ret))
    27 
    28 l = [11,22,3,45,54]
    29 res = pickle.dumps(l)
    30 print(res)
    31 
    32 pickle.dump(d,open('ethan.txt','ab')) # ==> 将字典、元组、列表转换成二进制写入文档
    33 
    34 # 注意 dump load 不要一起运行,会报错,一步一步来
    35 
    36 f = open('ethan.txt','rb')
    37 r = pickle.loads(f.read()) # ==> 将二进制转换成字典、列表、元组
    38 print(r)

     

    11:configpaser模块

    configparser用于处理特定格式的文件,其本质上是利用open来操作文件。

     1 # 注释1
     2 ;  注释2
     3  
     4 [section1] # 节点
     5 k1 = v1    #
     6 k2:v2       #
     7  
     8 [section2] # 节点
     9 k1 = v1    #
    10 
    11 指定格式
    指定格式

    举例:假如现在有一个ini的文件,内容如下:

    1 [poe]
    2 age = 12
    3 gender = 'female'
    4 edu = 'daxue'
    5 [jet]
    6 age = 19
    7 gender = 'male'

    1:利用configparser模块提供的功能,获取所有节点

    import configparser
    con = configparser.ConfigParser()#创建对象
    #con对象的read功能,打开文件读取文件,放进内存
    con.read("ini",encoding="utf-8")
    #con对象的sections,内在中寻找所有的[xxx]节点
    result = con.sections()
    print(result)
    #con对象的options功能,获取指定[xxx]节点下的内容
    ret = con.options("poe")
    print(ret)
    ##########################################
    ['poe', 'jet']
    ['age', 'gender', 'edu']

    2:获取指定节点下所有的键值对

    import configparser
    con = configparser.ConfigParser()
    con.read("ini",encoding="utf-8")
    
    ret = con.items('poe')
    print(ret)
    ##########################################
    [('age', '12'), ('gender', "'female'"), ('edu', "'daxue'")]

    3:获取指定节点下指定key的值

    import configparser
    con = configparser.ConfigParser()
    con.read("ini",encoding="utf-8")
    
    ret = con.get("poe","age")
    print(ret)
    ##########################################
    12

    4:检查、删除、添加节点

     1 import configparser
     2 con = configparser.ConfigParser()
     3 con.read("ini",encoding="utf-8")
     4 
     5 # 检查节点是否存在,存在返回True,否则返回False
     6 has_sec = con.has_section("poe")
     7 print(has_sec)
     8 
     9 # 添加节点
    10 con.add_section("andy")
    11 con.write(open("ini","w"))
    12 
    13 # 删除节点
    14 con.remove_section("trim")
    15 con.write(open("ini","w"))

    5:检查、删除、设置指定组内的键值对

     1 import configparser
     2 con = configparser.ConfigParser()
     3 con.read("ini",encoding="utf-8")
     4 
     5 # 检查andy节点下是否存在hobby键
     6 has_sec = con.has_option("andy","hobby")
     7 print(has_sec)
     8 
     9 # 删除
    10 con.remove_option("andy","hobby")
    11 con.write(open("ini","w"))
    12 
    13 # 设置
    14 con.set("andy","from","beijing")
    15 con.write(open("ini","w"))

    总结:

    增:

    1. obj.add_section(块节点名称)   增加一个块节点
    2. obj.set(块节点名称,键,值)         在指定的块节点下增加键值

    删:

    1. obj.remove_section(块节点名称)             删除指定块节点(连同该块节点下的所有键值都删除)
    2. obj.remove_option(块节点名称,该块节点下的键名)             删除指定块节点下指定键的键值对

    改:

    1. obj.set(块节点名称,键,值) 

    查:

    1. obj.sections()                 查询所有的块节点(且称之为块节点,如:上面文件中的[poe],[jet]),返回一个列表
    2. obj.options(块节点名称)              查询指定块节点下的所有键,返回一个列表
    3. obj.items(块节点名称)                 查询指定块节点下的所有键及值,返回一个列表(每个键值对保存为一个元组)
    4. obj.get(块节点名称,块节点下的键)                      查询指定块节点下,键所对就的值
    5. obj.has_section(块节点名称)                                查询块节点是否存在
    6. obj.has_option(块节点名称,块节点下的键)        查询指定块节点下的键是否存在

     

     

     

    12:hashlib

    用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

    import hashlib
     
    # ######## md5 ########
    hash = hashlib.md5()
    # help(hash.update)
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())
    print(hash.digest())
     
     
    ######## sha1 ########
     
    hash = hashlib.sha1()
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())
     
    # ######## sha256 ########
     
    hash = hashlib.sha256()
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())
     
     
    # ######## sha384 ########
     
    hash = hashlib.sha384()
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())
     
    # ######## sha512 ########
     
    hash = hashlib.sha512()
    hash.update(bytes('admin', encoding='utf-8'))
    print(hash.hexdigest())

    以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。(推荐使用此方法)

    import hashlib
     
    # ######## md5 ########
     
    hash = hashlib.md5(bytes('898oaFs09f',encoding="utf-8"))
    hash.update(bytes('admin',encoding="utf-8"))
    print(hash.hexdigest())

    python内置还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密

    import hmac
     
    h = hmac.new(bytes('898oaFs09f',encoding="utf-8"))
    h.update(bytes('admin',encoding="utf-8"))
    print(h.hexdigest())

     基于加密的登录程序:

    import hashlib
    def md5(arg) :
        p = hashlib.md5(bytes('admin',encoding='utf-8'))
        p.update(bytes(arg,encoding='utf-8'))
        return p.hexdigest()
    
    def register(user,pwd) :
        with open("db","a",encoding="utf-8") as f :
            temp = user + "|" + md5(pwd)
            f.write(temp)
    def login(user,pwd):
        with open('db','r',encoding="utf-8") as f :
            for line in f:
                u,p = line.strip().split("|")
                if u == user and p == md5(pwd):
                    return True
        return False
    i = input("1:login 2:register")
    if i == '2':
        user = input('username : ')
        pwd = input('password : ')
        register(user,pwd)
    elif i == '1':
        user = input('username :')
        pwd = input('password :')
        if login(user,pwd) :
            print('login success')
        else:
            print('login failed')
    用户登录

     13:subprocess模块

    执行shell命令

    call 

    执行命令,返回状态码

    ret = subprocess.call(["ls", "-l"], shell=False)
    ret = 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)

    subprocess.Popen(...)

    用于执行复杂的系统命令

    参数:

    1. args:shell命令,可以是字符串或者序列类型(如:list,元组)
    2. bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
    3. stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
    4. preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
    5. close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
    6. 所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
    7. shell:同上
    8. cwd:用于设置子进程的当前目录
    9. env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
    10. universal_newlines:不同系统的换行符不同,True -> 同意使用
    11. startupinfo与createionflags只在windows下有效
    12. 将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
    import subprocess
    ret1 = subprocess.Popen(["mkdir","t1"])
    ret2 = subprocess.Popen("mkdir t2", shell=True)

    终端输入的命令分为两种:

    1. 输入即可得到输出,如:ifconfig
    2. 输入进行某环境,依赖再输入,如:python
    import subprocess
    
    obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)
    import subprocess
    
    obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
    obj.stdin.write("print(1)
    ")
    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)
    
    import subprocess
    
    obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
    obj.stdin.write("print(1)
    ")
    obj.stdin.write("print(2)")
    
    out_error_list = obj.communicate()
    print(out_error_list)
    
    import subprocess
    
    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)
    

     14:login模块

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

    1、单文件日志

    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
    

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

    日志记录格式:

    2、多文件日志

    对于上述记录日志的功能,只能将日志记录在单文件中,如果想要设置多个日志文件,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.addHandler(file_1_2)
    
    
    # 写日志
    logger1.critical('1111')
    
    # 定义文件
    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 文件中
  • 相关阅读:
    html单引号,双引号转义
    把文章里边的html标签去掉(去掉文字的样式,显示css设置的样式)
    java缓存适合使用的情况
    Java内存缓存
    springmvc怎么重定向,从一个controller跳到另一个controller
    jquery 获取标签名(tagName)
    jQuery判断checkbox是否选中的3种方法
    判断一组checkbox中是否有被选中的
    在O(N)时间内求解 正数数组中 两个数相加的 最大值
    两种方法求解 正数数组中 两个数相减 的最大值
  • 原文地址:https://www.cnblogs.com/ginvip/p/6257386.html
Copyright © 2020-2023  润新知