模块

1.模块

模块定义

什么是模块:本质就是.py文件,封装语句的最小单位。

自定义模块:实际上就是定义.py,其中可以包含:变量定义,可执行语句,for循环,函数定义等等,他们统称模块的成员。

1.模块的运行方式:

  • 脚本方式:直接用解释器执行。或者PyCharm中右键运行。
  • 模块方式:被其他的模块导入。为导入它的模块提供资源(变量,函数定义,类定义等)。

2.__name__属性的使用:

在脚本方式运行时,__name__是固定的字符串:main

在以模块方式被导入时,__name__就是本模块的名字。

在自定义模块中对__name__进行判断,决定是否执行可执行语句:开发阶段,就执行,使用阶段就不执行。

3.系统导入模块的路径

  • 内存中:如果之前成功导入过某个模块,直接使用已经存在的模块
  • 内置路径中:安装路径下:Lib
  • PYTHONPATH:import时寻找模块的路径。
  • sys.path:是一个路径的列表。

如果上面都找不到,就报错。

通过动态修改sys.path的方式将自定义模块添加到sys.path中。

os.path.dirname():获取某个路径的父路径。通常用于获取当前模块的相对路径

import sys
import os
sys.path.append(os.path.dirname(__file__) + '/aa')

4.导入模块的多种方式:

  • import xxx:导入一个模块的所有成员
  • import aaa,bbb:一次性导入多个模块的成员。不推荐这种写法,分开写。
  • from xxx import a:从某个模块中导入指定的成员。
  • from xxx import a,b,c:从某个模块中导入多个成员。
  • from xxx import *:从模块中导入所有成员。

5.import xxx 和 from xxx import * 的区别

第一种方式在使用其中成员时,必须使用模块名作为前缀。不容易产生命名冲突。

第二种方式在使用其中成员时,不用使用模块名作为前缀,直接使用成员名即可。但是容易产生命名冲突。在后定义的成员生效(把前面的覆盖了。)

6.怎么解决名称冲突的问题

  • 改用import xxx这种方式导入。
  • 自己避免使用同名
  • 使用别名解决冲突

7.使用别名:alias

给成员起别名,避免名称冲突。

from my_module import age as a

给模块起别名,目的简化书写。

import my_module as m

8.from xxx import * 控制成员被导入

默认情况下,所有的成员都会被导入。

__all__是一个列表,用于表示本模块可以被外界使用的成员。元素是成员名的字符串。

注意:

__all__只是对from xxx import *这种导入方式生效。其余的方式都不生效。

9.相对导入

针对某个项目中的不同模块之间进行导入,称为相对导入。

只有一种格式:

from 相对路径 import xxx

相对路径:包含了点号的一个相对路径。

. 表示的是当前的路径。

..表示的是父路径。

...表示的是父路径的父路径。

# 相对导入同项目下的模块
# from ..z import zz            # 容易向外界暴露zz模块
from ..z.zz import *



# 不使用相对导入的方式,导入本项目中的模块
# 通过当前文件的路径找到z的路径
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__)) + '/z')
from zz import *

10.常用模块:random

此模块提供了和随机数获取相关的方法:

  • random.random():获取[0.0,1.0)范围内的浮点数
  • random.randint(a,b):获取[a,b]范围内的一个整数
  • random.uniform(a,b):获取[a,b)范围内的浮点数
  • random.shuffle(x):把参数指定的数据中的元素打乱。参数必须是一个可变的数据类型。
  • random.sample(x,k):从x中随机抽取k个数据,组成一个列表返回

一、hashlib模块

也被称为哈希算法、摘要算法、加密算法、散列算法。此模块相当于一个算法的集合,这里面包含着很多的算法(如MD5、SHA1、SHA256、SHA512……),算法越高,转化成的结果越复杂,安全程度越高,相应的效率就会越低。

  1. 用途

  2. 密码加密
  3. 文件一致性校验

  4. 特性

  5. hashlib算法将bytes类型字节转化为固定长度的16进制数字组成的字符串
  6. 不同的bytes利用相同的算法(MD5)转化成的结果一般不同
  7. 相同的bytes利用相同的算法(MD5)转化成的结果一定相同
  8. hashlib算法理论上不可逆(MD5被中国王晓云破解了)

    #计算一个字符串的MD5
    import hashlib #加载hashlib模块
    s='123456'
    md5 = hashlib.md5() #开启加密机(可选参数为盐,默认为空)
    md5.update(s.encode('utf-8')) #把要加密的内容转成bytes后放到加密机里
    print(md5.hexdigest()) #产生加密结果并打印

    执行结果:e10adc3949ba59abbe56e057f20f883e

    #计算一个字符串的MD5(加固定的盐)
    import hashlib
    s='123456'
    md5 = hashlib.md5(b'salt') #加固定的盐b'salt'
    md5.update(s.encode('utf-8'))
    print(md5.hexdigest())

    执行结果:f51703256a38e6bab3d9410a070c32ea
    注意:盐也需要转化成bytes类型,可以是b'xxx'形式,或者是xxx.encode('utf-8')

    #计算一个字符串的MD5(加动态的盐)
    import hashlib
    username='oddgod'
    s='123456'
    md5 = hashlib.md5(username[::2].encode('utf-8')) #加动态的盐
    md5.update(s.encode('utf-8'))
    print(md5.hexdigest())

    执行结果:0007ff9bb8dde5ea966b88afcdbacfd2

    #Low版文件校验——一次性读取整个文件,容易撑爆内存
    import hashlib
    with open('filename.png', mode='rb') as f:
    md5 = hashlib.md5()
    md5.update(f.read())
    print(md5.hexdigest())

    执行结果:888f3d2b673e92aeefee78c3d3864532

    #高大上版文件校验——每次最多读取1024字节
    import hashlib
    with open('filename.png', mode='rb') as f:
    md5 = hashlib.md5()
    while 1:
    content = f.read(1024) #每次最多读取1024字节
    if content:
    md5.update(content)
    else:
    print(md5.hexdigest())
    break

    执行结果:888f3d2b673e92aeefee78c3d3864532

二、序列化模块(json、pickle)

序列化模块就是将一个常见的数据结构转化成一个特殊的序列,并且这个特殊的序列还可以反解回去。

它的主要用途:文件读写数据、网络传输数据。

  1. json模块

  2. 被大多数语言广泛应用的一种数据交换格式
  3. json:部分python数据类型<===>特殊的str(json字符串)
  4. json序列化支持的Python数据类型:dict, list, tuple, str,int, float,True,False,None
  5. json序列化不支持set数据类型
  6. tuple经过json序列化再反序列化后,将变为list
  7. json以字符为单位进行序列化和反序列化
  8. python→json
  9. json→python
  10. dumps、loads可用于网络传输或文件读写(推荐)
    dump、load只用于文件读写(不推荐)
  11. json流程图

    使用dumps、loads转换数据类型(网络传输)

    import json
    dic = {'k1':'v1','k2':'v2','k3':'v3'}
    s = json.dumps(dic) #序列化:将字典转换成json字符串
    print(s,type(s))
    dic2 = json.loads(s)
    print(dic2,type(dic2)) #反序列化:将json字符串转换成字典

    执行结果:
    {"k1": "v1", "k2": "v2", "k3": "v3"} <class 'str'>
    {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} <class 'dict'>
    注意,json转换完的字符串类型的字典中的字符串是由""表示的

    使用dumps、loads进行文件单次读写

    import json
    l1 = [1, 2, 3, {'name': 'alex'}, False]
    with open('通用.txt', encoding='utf-8', mode='w') as f1:
    s1 = json.dumps(l1)
    f1.write(s1)
    #为什么写的是jason字符串(s1)而不是bytes?因为open()已将相关功能封装进去帮你转换成bytes了
    with open('通用.txt', encoding='utf-8') as f2:
    s2 = f2.read()
    l2 = json.loads(s2)
    print(l2, type(l2))

    执行结果:[1, 2, 3, {'name': 'alex'}, False] <class 'list'>

    使用dump、load进行文件单次读写

    import json
    l1 = [1, 2, 3, {'name': 'alex'}, False]
    with open('通用.txt',encoding='utf-8',mode='w') as f1:
    json.dump(l1,f1)
    with open('通用.txt',encoding='utf-8') as f2:
    l2 = json.load(f2)
    print(l2,type(l2))

    执行结果:[1, 2, 3, {'name': 'alex'}, False] <class 'list'>

    文件多次读写时,推荐使用dumps、loads,然后每次写时手动加换行符\n

    直接用dump和load进行多次读写会报错

    import json
    dic1 = {'username': 'alex'}
    dic2 = {'username': '太白'}
    dic3 = {'username': '大壮'}
    with open('通用.txt',encoding='utf-8',mode='w') as f1:
    f1.write(json.dumps(dic1) + '\n') #json字符串也是字符串,可以与普通的字符串进行拼接
    f1.write(json.dumps(dic2) + '\n')
    f1.write(json.dumps(dic3) + '\n')
    with open('通用.txt',encoding='utf-8') as f2:
    for line in f2:
    print(json.loads(line)) #json.loads自动将每行最后的换行符去掉了

    执行结果:
    {'username': 'alex'}
    {'username': '太白'}
    {'username': '大壮'}

  12. pickle模块

  13. 只能在Python语言中使用,不适用于其他语言。
  14. pickle:全部python数据类型<===>特殊的bytes(pickle字节串)
  15. 支持Python所有的数据类型包括实例化对象。它能将这些所有的数据结构序列化成特殊的bytes,然后还可以反序列化还原。
  16. pickle以字节为单位进行序列化和反序列化
  17. pickle流程图

    #使用dumps、loads转换数据类型(网络传输)
    import pickle
    dic = {'k1':'v1'}
    b = pickle.dumps(dic) #序列化:将字典转换成pickle字节串
    print(b,type(b))
    dic2 = pickle.loads(b)
    print(dic2,type(dic2)) #反序列化:将pickle字节串转换成字典

    #使用dumps、loads进行文件单次读写
    import pickle
    l1 = [1, 2, 3, {'name': 'alex'}, False]
    with open('通用.txt', mode='wb') as f1:
    b1 = pickle.dumps(l1)
    f1.write(b1)
    with open('通用.txt', mode='rb') as f2:
    b2 = f2.read()
    l2 = pickle.loads(b2)
    print(l2, type(l2))

    执行结果:
    [1, 2, 3, {'name': 'alex'}, False] <class 'list'>
    和上面json的例子相比的不同之处:第一,mode都带b,因为json以字符为单位而pickle以字节为单位;第二,没有encoding='utf-8',同理。

    #使用dump、load进行文件单次读写
    import pickle
    l1 = [1, 2, 3, {'name': 'alex'}, False]
    with open('通用.txt',mode='wb') as f1:
    pickle.dump(l1,f1)
    with open('通用.txt',mode='rb') as f2:
    l2 = pickle.load(f2)
    print(l2,type(l2))

    执行结果:[1, 2, 3, {'name': 'alex'}, False] <class 'list'>

    #使用dump、load进行文件多次读写(知道读几次)
    #pickle模块下不能使用dumps、loads进行文件多次读写
    import pickle
    dic1 = {'username': 'alex'}
    dic2 = {'username': '太白'}
    dic3 = {'username': '大壮'}
    with open('通用.txt',mode='wb') as f1:
    pickle.dump(dic1, f1)
    pickle.dump(dic2, f1)
    pickle.dump(dic3, f1)
    with open('通用.txt',mode='rb') as f2:
    print(pickle.load(f2))
    print(pickle.load(f2))
    print(pickle.load(f2))

    执行结果:
    {'username': 'alex'}
    {'username': '太白'}
    {'username': '大壮'}

    #使用dump、load进行文件多次读写(不知道读几次)
    #由于上例读的时候一般不知道应该读多少次(多读一次就报错,还不像json那样可以for line...循环读),因此读的部分可以改写成本例try的形式
    import pickle
    dic1 = {'username': 'alex'}
    dic2 = {'username': '太白'}
    dic3 = {'username': '大壮'}
    with open('通用.txt',mode='wb') as f1:
    pickle.dump(dic1, f1)
    pickle.dump(dic2, f1)
    pickle.dump(dic3, f1)
    with open('通用.txt',mode='rb') as f2:
    while 1:
    try:
    print(pickle.load(f2))
    except EOFError:
    break

    执行结果:
    {'username': 'alex'}
    {'username': '太白'}
    {'username': '大壮'}

三.正则表达式

1.正则表达式

1.模块和实际工作的关系

  • 有了re模块就可以操作正则表达式

2.正则表达式 :一套规则- 匹配字符串的

  • 能做什么
    1.检测一个输入的字符串是否合法--(web开发项目 表单)
    用户输入一个内容的时候,我们要提前做检测,能够提高程序的效率并且减轻服务器的压力
    2.从一个大文件中找到所有符合规则的内容--(日志分析/爬虫)

               能够高效的从一大段文字中快速找符合规则的内容
  • 正则规则
    所有的规则中的字符就可以刚刚好匹配到字符串中的内容

    字符组 [] 描述的是一个位置上能出现的所有可能性 可以接受范围

    [abc]一个中括号只表示一个字符位置

    匹配到a或b或c

    根ascii进行范围的对比

    2.元字符

  • 在正则表达式中能够帮助我们表示匹配的内容的符号都是正则中的 元字符

    [0-9] --> \d 匹配一位任意的数字

    [0-9a-zA-Z] -->\w数字字母下划线

    空白(空格\tab\enter) -->( 空格键  \t \n)

    所有的空白都可以用\s

    . 表示除了换行符之外的所有

    元字符 -- 匹配内容的规则
    []  描述的是一个位置上能出现的所有可能性
    [^] 与[]相反
    \d  表示匹配一位任意数字 digit
    \w  表示匹配数字字母下划线 word
    \s    空白
    \t    tab
    \n    enter
    \W  非数字字母下划线
    \D  非数字
    \S  非空白
    [\d]  \d
    [\d\D] [\w\W] [\s\S]  表示匹配所有
    .   匹配除了换行符之外的所有
    [^\d]  匹配所有的非数字
    [^1]  匹配所有的非数字
    ^     匹配一个字符串的开始
    $     匹配一个字符串的结尾
    a表达式|b表达式     匹配a或者b表达式中的内容,如果匹配a成功了,不会继续和b匹配,所以,如果两个规则有重叠部分,总是把长的放在前面
    ()    # 约束 | 描述的内容的范围问题
  • 量词
    • {n}  表示匹配n次
      {n,} 表示匹配至少n次
      {n,m}表示至少匹配n次,至多m次
      ? 表示匹配0次或1次 {0,1}
      + 表示1次或多次    {1,}
      * 表示0次或多次    {0,}

      匹配0次
      # 整数 \d+
      # 小数 \d+.\d+
      # 整数或小数 : \d+.?\d*

        # 分组的作用 : \d+(\.\d+)?

      # 手机号码
      # 1 3-9 11位
      # 1[3-9]\d{9}

      # 判断用户输入的内容是否合法,如果用户输入的对就能查到结果,如果输入的不对就不能查到结果
      # ^1[3-9]\d{9}$
      # 从一个大文件中找到所有符合规则的内容
      # 1[3-9]\d{9}
  • 贪婪匹配:在量词允许下的情况下,尽量多的匹配内容
    .* x 表示匹配任意字符,任意多次但是遇到最后一个x才停下来
  • 非贪婪(惰性)匹配
    .*?x 表示匹配任意字符,任意多次但是一旦遇到x就停下来
  • 转义符 原本有特殊意义的字符,到了表达它本身的意义的时候,需要转义
    [.()*+?] 所有的内容在字符组中会取消它的特殊意义
    [a-c] -在字符组中表示范围,如果不希望它表示范围,需要转义,或者放在字符组的最前面\最后面

2.re模块

  • findall 返回所有满足匹配条件的结果,放在列表里
    import re
    ret = re.findall('a', 'eva egon yuan') # 返回所有满足匹配条件的结果,放在列表里
    print(ret) #结果 : ['a', 'a']
    findall的优先级查询
    为什么要用分组:因为把想要的内容放分组里
    如何取消分组优先:如果在写正则的时候由于不得已的原因呢,导致不要的内容也得写在分组里,(?:)取消这个分组的优先显示
    import re
    ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
    print(ret) # ['oldboy'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
    ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
    print(ret) # ['www.oldboy.com']

  • serach 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None
    ret = re.search('a', 'eva egon yuan')
    print(ret.group()) #结果 : 'a'
    serach 优先级查询
    还是按照完整的正则进行匹配,显示也是显示匹配到的第一个内容,但是我们可以通过给group方法穿参数来获取具体分组的内容
    import re
    ret = re.search('9(\d)(\d)','1974asd9308ur')
    print(ret)
    if ret:
    print(ret.group()) 不写默认括号里为0 全部 打印
    print(ret.group(1))
    print(ret.group(2))
  • split 分隔
    splitret = re.split('\d+','alex222wusir')

    ret = re.split('\d(\d)\d','alex123wusir')
    
    print(ret)
    
    split的优先级
    
    ret=re.split("\d+","eva3egon4yuan")
    print(ret) #结果 : ['eva', 'egon', 'yuan']
    
    ret=re.split("(\d+)","eva3egon4yuan")
    print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']
    
    #在匹配部分加上()之后所切出的结果是不同的,
    #没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
    #这个在某些需要保留匹配部分的使用过程是非常重要的。
  • sub 替换
    # sub 替换
    # ret = re.sub('\d+','H','alex123wusir456',1)
    # print(ret)
    ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1)#将数字替换成'H',参数1表示只替换1个
    print(ret) #evaHegon4yuan4
  • subn
    # subn
    # ret = re.subn('\d+','H','alex123wusir456')
    # print(ret)
    ret = re.subn('\d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)
    print(ret)
  • match 同search,不过尽在字符串开始处进行匹配
    ret = re.match('a', 'abc').group() # 同search,不过尽在字符串开始处进行匹配
    print(ret)
    #结果 : 'a'

    # match  用户输入的内容匹配的时候,要求用户输入11位手机号码,^手机号正则$
    # match('手机号正则$','123eva456taibai')  规定这个字符号必须是什么样的
    # search('^手机号正则$','123eva456taibai') 用来寻找这个字符串中是不是含有满足条件的子内容
    
    # ret = re.match('\d+','123eva456taibai')
    # print(ret.group())
    
    # ret = re.search('^\d+','123eva456taibai')
    # print(ret.group())
  • compile -- 节省代码时间的工具
    假如同一个正则表达式要被使用多次,节省了多次解析同一个正则表达式的时间

    # ret = re.compile('\d+')
    # res1 = ret.search('alex37176')
    # res2 = ret.findall('alex37176')
    # print(res1)
    # print(res2)
    
    # finditer -- 节省空间
    # ret = re.finditer('\d+','agks1ak018093')
    # for i in ret:
    #     print(i.group())
    
    # 先compile(如果没有重复使用同一个正则,也不能节省时间)
    # 再finditer
    # ret= re.compile('\d+')
    # res = ret.finditer('agks1ak018as093')
    # for r in res:
    #     print(r.group())

    # re模块的常用方法
    # findall(正则,待匹配字符串,flag) : 返回所有匹配项的列表
    # search : 返回一个变量,通过group取到的是第一个匹配的项
    # finditer :返回一个迭代器,通过迭代取到的是一个变量,通过group取值
    # match : 从头开始找第一个,其他和search一样

      # compile(正则):同一个正则表达式需要多次使用的时候提前编译来节省时间
    
      # split 通过正则表达式匹配的内容进行分割
      # sub 替换,通过正则表达式匹配的内容来进行替换
      # subn 替换,在sub的基础上,返回一个元组,第一个内容是替换结果,第二个是替换次数

3.分组命名

1.分组命名:(?P<名字>正则表达式)
  1. 分组命名有的时候我们要匹配的内容是包含在不想要的内容之中的, 只能先把不想要的内容匹配出来,然后再想办法从结果中去掉:(?P正则) (?P=组名)
    import re

    ret = re.search('\d(\d)\d(\w+?)(\d)(\w)\d(\d)\d(?P<name1>\w+?)(\d)(\w)\d(\d)\d(?P<name2>\w+?)(\d)(\w)',
    
    '123abc45678agsf_123abc45678agsf123abc45678agsf')
    
    #
    
    print(ret.group('name1'))
    
    print(ret.group('name2'))
    
    (?P<名字>正则表达式)
    
    ret.group('名字')
    
    分组命名的引用
    
    import re
    
    exp= '<abc>akd7008&(&)hgdwuih</abb>008&(&)hgdwuih</abd>'
    
    ret= re.search('<(?P<tag>\w+)>.*?</(?P=tag)>',exp)
    
    print(ret)
    
    import re
    
    exp= '<abc>akd7008&(&)hgdwuih</abc>008&(&)hgdwuih</abd>'
    
    ret= re.search(r'<(\w+)>.*?</\1>',exp)
    
    ret= re.search('<(\w+)>.*?</\1>',exp)
    
    print(ret)
    
    import re
    
    ret=re.findall(r"\d+.\d+|(\d+)","1-2(60+(-40.35/5)-(-43))")
    
    print(ret)
    
    ret = ['1', '2', '60', '', '5', '4', '3','','']
    
    ret.remove('')
    
    print(ret)
    
    ret = filter(lambda n:n,ret)
    
    print(list(ret))
    
    分组命名(?P<组名>正则) (?P=组名)
    
    有的时候我们要匹配的内容是包含在不想要的内容之中的,# 只能先把不想要的内容匹配出来,然后再想办法从结果中去掉

4.os模块

 os
    # 文件和文件夹相关的
        # os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
        # os.remove()  删除一个文件
        # os.rename("oldname","newname") 重命名文件/目录
        # os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
        # os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
        # os.makedirs('dirname1/dirname2')  可生成多层递归目录
        # os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    # 和执行操作系统命令相关
        # os.popen("bash command).read()  运行shell命令,获取执行结果
        #os.system("bash command")运行shell命令,直接显示
        # import os
        # os.system('dir')
        # ret = os.popen('dir')
        # print(ret.read())
    # 工作目录:在哪个文件下执行的这个py文件,哪一个目录就是你的工作目录
        # import os
        # os.chdir('D:\python_22\day21')
        # print('-->',os.getcwd())
        # open('s21day21tmp','w').close()
    # os.path
        # os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
        # os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
        # os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False

        # ps.path.basename  获取这个路径的最后一个值
            # D:\python_22\day21  --> day21
            # D:\python_22\day21\3.递归习题.py   --> 3.递归习题.py
        # os.path.dirname 获取这个路径的上一级目录
            # D:\python_22\day21  --> D:\python_22
            # D:\python_22\day21\3.递归习题.py --> D:\python_22\day21
        # os.path.split(path)
            # D:\python_22\day21\3.递归习题.py -->(D:\python_22\day21,3.递归习题.py)
        # os.path.join(dirname,basename)   跨平台的

        # os.path.getsize(path) 返回path的大小
        # oa.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
       # oa.path.getatimes(path)  返回path所指向的文件或者目录的最后访问时间

5.sys模块

# sys 和python解释器交互的
    # sys.path 模块搜索路径
    # sys.argv 在运行python脚本的时候写在python命令后面的是啥,打印出来的就是啥
    # sys.modules 查看导入了哪些模块

用sys登陆验证
# import sys
# if sys.argv[1] == 'alex' and sys.argv[2] == 'sb':
#     print('登录成功')

6.shutil模块

#shutil.copy2 拷贝文件
 shutil.copy2('原文件', '现文件')
 shutil.copy2('file', 'temp')

#shutil.copytree 拷贝目录
shutil.copytree("原目录", "新目录",ignore=shutil.ignore_patterns("*.pyc"))
shutil.copytree("/Users/jingliyang/PycharmProjects/面试题/常用模块/logging模块", "logging模块2", ignore=shutil.ignore_patterns("__init__.py"))


#shutil.rmtree 删除目录
shutil.rmtree("D:\python_22\day21\outer3")
shutil.rmtree("temp", ignore_errors=True)
shutil.rmtree("logging模块2", ignore_errors=True)

#shutil.move 移动文件\目录
shutil.move("logging模块", "logging2", copy_function=shutil.copy2)

#获取磁盘使用空间
 total, used, free = shutil.disk_usage("c:\\")
 print("当前磁盘共: %iGB, 已使用: %iGB, 剩余: %iGB"%(total / 1073741824, used / 1073741824, free / 1073741824))
#shutil.make_archive 压缩文件
shutil.make_archive('压缩文件夹的名字', 'zip','待压缩的文件夹路径')
 shutil.make_archive('logging2', 'zip','/Users/jingliyang/PycharmProjects/面试题/常用模块/随机数')
    
#shutil.unpack_archive 解压文件
shutil.unpack_archive('zip文件的路径.zip','解压到目的文件夹路径')
shutil.unpack_archive('/Users/jingliyang/PycharmProjects/面试题/常用模块/shutil模块/logging2.zip','/Users/jingliyang/PycharmProjects/面试题/常用模块/shutil模块/tmp')

7.logging模块

1.无论你希望日志里打印哪些内容,都得你自己写,没有自动生成日志这种事儿

# 为什么要写log?
    # log是为了排错
    # log用来做数据分析的

# 购物商城 - 数据库里
    # 什么时间购买了什么商品
    # 把哪些商品加入购物车了

# 做数据分析的内容 - 记录到日志
# 1.一个用户什么时间在什么地点 登录了购物程序
# 2.搜索了哪些信息,所长时间被展示出来了
# 3.什么时候关闭了软件
# 4.对哪些商品点进去看了

# 计算器
    # (1+2)*3/4
    # 计算乘法(表达式):
       # 记录日志:计算乘法表达式是什么,结果是什么
       # return
    # 计算除法
        # 记录日志:表达式是什么,结果是什么
       # return
    # 计算小括号内的
    # 计算加法
    # 计算减法

# 1.用来记录用户的行为 - 数据分析
# 2.用来记录用户的行为 - 操作审计
# 3.排查代码中的错误

import logging
# 输出内容是有等级的 : 默认处理warning级别以上的所有信息
# logging.debug('debug message')     # 调试
# logging.info('info message')         # 信息
# logging.warning('warning message')   # 警告
# logging.error('error message')       # 错误
# logging.critical('critical message') # 批判性的


# def cal_mul(exp):
#     exp = 4*6
#     logging.debug('4*6 = 24')
#     return 24
# def cal_div():
#     pass
# def cal_add():
#     pass
# def cal_sub(exp):
#     exp = 3-24
#     logging.debug('cal_sub :3-24 = 21')
#     return 21

# def cal_inner_bracket(exp2):
#     exp2 = 3-4*6
#     ret = cal_mul(4*6)
#     exp2 = 3-24
#     ret = cal_sub(3-24)
#     logging.debug('3-4*6 = -21')
#     return -21
#
# def main(exp):
#     exp =(1+2*(3-4*6))/5
#     ret = cal_inner_bracket(3-4*6)
#     return ret
#
# logging.basicConfig(level=logging.DEBUG)
# ret = main('(1+2*(3-4))/5')
# print(ret)

# 1.无论你希望日志里打印哪些内容,都得你自己写,没有自动生成日志这种事儿
# logging.basicconfig
# 输出到屏幕
# logging.basicConfig(
#     format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s:  %(message)s',
#     datefmt='%Y-%m-%d %H:%M:%S %p',
# )
# logging.warning('warning message test2')
# logging.error('error message test2')
# logging.critical('critical message test2')

# 输出到文件,并且设置信息的等级
# logging.basicConfig(
#     format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s:  %(message)s',
#     datefmt='%Y-%m-%d %H:%M:%S %p',
#     filename='tmp.log',
#     level= logging.DEBUG
#
# )
# logging.debug('debug 信息错误 test2')
# logging.info('warning 信息错误 test2')
# logging.warning('warning message test2')
# logging.error('error message test2')
# logging.critical('critical message test2')



# 要记住的
# --------------------------------------------------------------------------------------------------
# 同时向文件和屏幕上输出 和 乱码
# fh = logging.FileHandler('tmp.log',encoding='utf-8')
# # fh2 = logging.FileHandler('tmp2.log',encoding='utf-8')
# sh = logging.StreamHandler()
# logging.basicConfig(
#     format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s:  %(message)s',
#     datefmt='%Y-%m-%d %H:%M:%S %p',
#     level= logging.DEBUG,
#     # handlers=[fh,sh,fh2]
#     handlers=[fh,sh]
# )
# logging.debug('debug 信息错误 test2')
# logging.info('warning 信息错误 test2')
# logging.warning('warning message test2')
# logging.error('error message test2')
# logging.critical('critical message test2')

# 做日志的切分
# import time
# from logging import handlers
# sh = logging.StreamHandler()
# rh = handlers.RotatingFileHandler('myapp.log', maxBytes=1024,backupCount=5)   # 按照大小做切割
# fh = handlers.TimedRotatingFileHandler(filename='x2.log', when='s', interval=5, encoding='utf-8')
# logging.basicConfig(
#     format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s:  %(message)s',
#     datefmt='%Y-%m-%d %H:%M:%S %p',
#     level= logging.DEBUG,
#     # handlers=[fh,sh,fh2]
#     handlers=[fh,rh,sh]
# )
# for i in range(1,100000):
#     time.sleep(1)
#     logging.error('KeyboardInterrupt error %s'%str(i))

重要的logging的日志切分格式

# 做日志的切分
 import time
 from logging import handlers
 sh = logging.StreamHandler()
rh = handlers.RotatingFileHandler('myapp.log', maxBytes=1024,backupCount=5)   # 按照大小做切割
fh = handlers.TimedRotatingFileHandler(filename='x2.log', when='s', interval=5, encoding='utf-8')
logging.basicConfig(
  format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s:  %(message)s',   datefmt='%Y-%m-%d %H:%M:%S %p',   level= logging.DEBUG,    handlers=[fh,sh,fh2]    handlers=[fh,rh,sh]
 )

转载于:https://www.cnblogs.com/cui-xuefei/p/11201607.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值