第六章 模块

6.1前言

  1. 什么是模块
    • py文件 写好了的 对程序员直接提供某方面功能的文件
    • import
    • rom import 名字
  2. 什么是包
    • 文件夹 存储了多个py文件的文件夹
    • 如果导入的是一个包,这个包里的模块默认是不能用的
    • 导入一个包相当于执行__init__py文件中的内容

6.1 模块初步(import)

# import 模块名  # 调用py的内置模块,

6.1.1 sys.模块

### py  解释器相关的数据
import sys
sys.getrefcount()   # 获取一个值的引用次数,用得少,不重要
a = [11,22,33]
b = a
print(sys.getrefcount(a))

###sys.getrecursionlimit()
print(sys.getrecursionlimit())  # 1000次,python默认支持的递归数量.实际使用用个人的电脑配置有关

###sys.stdout.write  --> print    (进度)
import time
for i in range(100):
    msg = '进度条跑到%s%%\r' %i    # \r 光标回到当前行的起始位置(不是覆盖.,是清空)
    print(msg , end = '')
    time.sleep(0.5)  # 暂停0.5s后再运行
    
### sys.agrv  #### 获取用户执行脚本时,传入的参数。得到的是一个列表,第一个元素是脚本文件.py
##  Sys.argv[ ]其实就是一个列表,里边的项为用户输入的参数,关键就是要明白这参数是从程序外部输入的,而非代码本身的什么地方,要想看到它的效果就应该将程序保存了,从外部来运行程序并给出参数。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
让用户执行脚本传入要删除的文件路径,在内部帮助用将目录删除。
C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test
C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py

"""
import sys

# 获取用户执行脚本时,传入的参数。
# C:\Python36\python36.exe D:/code/s21day14/7.模块传参.py D:/test
# sys.argv = [D:/code/s21day14/7.模块传参.py, D:/test]
path = sys.argv[1]

# 删除目录
import shutil
shutil.rmtree(path)
  1. sys.argv

  2. sys.path # 默认Python去导入模块时,会按照sys.path中的路径挨个查找。 ---> 本质是列表

  3. sys.exit( 0 ) 是正常退出 sys.exit( 1) 异常退出

  4. sys.modules

    sys.modules # 存储了当前程序中用到的所有模块,反射本文件中的内容
    sys.modules[__name__]---->指向本文件
    # '__main__': <module '__main__' from 'D:/code/day24/1.内容回顾.py'>
    

6.1.2 os 模块

和操作系统相关的数据。

  • os.path.exists(path) , 如果path存在,返回True;如果path不存在,返回False

  • os.stat('20190409_192149.mp4').st_size , 获取文件大小

  • os.path.getsize()-->获取文件大小

  • os.path.abspath() , 获取一个文件的绝对路径

    import os
    # 1. 读取文件大小(字节)
    file_size = os.stat('20190409_192149.mp4').st_size
    # 2.一点一点的读取文件
    read_size = with open('20190409_192149.mp4',mode='rb') as f1,open('a.mp4',mode='wb') as f2:    
        while read_size < file_size:        
            chunk = f1.read(1024) # 每次最多去读取1024字节        
            f2.write(chunk)        
            read_size += len(chunk)        
            val = int(read_size / file_size * 100)        
            print('%s%%\r' %val ,end='')
    
import os

os.path.exists(path)      #如果path存在,返回True;如果path不存在,返回False.文件路径

os.stat('20190409_192149.mp4').st_size   #  获取文件大小(字节大小)

os.path.abspath()   #  获取一个文件的绝对路径

os.path.dirname # 获取路径的上级目录(文件夹)


  • os.path.join ,路径的拼接

    import os
    path = "D:\code\s21day14" # user/index/inx/fasd/
    v = 'n.txt'     
    
    result = os.path.join(path,v)
    print(result)        # # D:\code\s21day14\n.txt
    result = os.path.join(path,'n1','n2','n3')
    print(result)      # D:\code\s21day14\n1\n2\n3
    
  • os.listdir , 查看一个目录下所有的文件【第一层】

    import os
    
    result = os.listdir(r'D:\code\s21day14')     # r,在字符创=串前面,转义符,把\n\t\r当做字符串.
    for path in result:
        print(path)
    
  • os.walk , 查看一个目录下所有的文件【所有层】

    import os
    
    result = os.walk(r'D:\code\s21day14')
    for a,b,c in result:
        # a,正在查看的目录 b,此目录下的文件夹  c,此目录下的文件
        for item in c:
            path = os.path.join(a,item)
            print(path)   # 还有其他很多用途
            
    获取文件夹大小,即遍历文件夹,将所有文件大小加和。遍历文件夹使用os.walk函数
    
      os.walk()可以得到一个三元tupple(dirpath, dirnames, filenames),
    
      1、第一个为起始路径,
    
      2、第二个为起始路径下的文件夹,
    
      3、第三个是起始路径下的文件。
    
      其中dirpath是一个string,代表目录的路径,dirnames是一个list,包含了dirpath下所有子目录的名字。filenames是一个list,包含了非目录文件的名字。这些名字不包含路径信息,如果需要得到全路径,需要使用os.path.join(dirpath, name).
    
    复制代码
    import os
    from os.path import join, getsize
    
    
    def getdirsize(dir):
        size = 0
        for root, dirs, files in os.walk(dir):
            size += sum([getsize(join(root, name)) for name in files])
        return size
    
    
    if __name__ == '__main__':
        filesize = getdirsize('E:\chengd')
        print('There are %.3f' % (filesize / 1024 / 1024 ), 'Mbytes in E:\\chengd')
    
    执行结果:
    There are 4747.763 Mbytes in E:\chengd
    
  • 转义符的使用

    v1 = r"D:\code\s21day14\n1.mp4"  (推荐)
    print(v1)
    
    
    v2 = "D:\\code\\s21day14\\n1.mp4"
    print(v2)
    
  • os.makedirs,创建目录和子目录--->比makedir 好用,只能创建一层目录

    import os
    file_path = r'E:\小莫的黄片库\绝对不能偷看\请输入密码\****.MP4'
    
    file_folder = os.path.dirname(file_path)
    if not os.path.exists(file_folder):
        os.makedirs(file_folder)
    
    with open(file_path,mode='w',encoding='utf-8') as f:
        f.write('asdf')
    
    
  • os.rename 重命名

    import os
    os.rename('db','sb')    # 原文件 ,现文件
    

6.1.3 shutil 模块

  • 删除目录

    import shutil
    shutil.rmtree(path)
    
import shutil


##删除目录(只能是文件夹)
shutil.rmtree('test')

## 重命名
shutil.move(old,new)  ,移动文件

##压缩文件
shutil.make_archive('压缩后文件名可以加文件路径','压缩格式zip等等','被压缩的文件/文件夹')

shutil.make_archive('zzh','zip','D:\code\s21day16\lizhong')

##解压文件
shutil.unpack_archive('要解压的文件夹',extract_dir=r'D:\code\xxxxxx\xxxx',格式:'zip')
 #                                    解压的路径
shutil.unpack_archive('zzh.zip',extract_dir=r'D:\code\xxxxxx\xxxx',format='zip')

举例

import shutil

shutil.rmtree('4567')     # 删除目录(只能是文件夹)

shutil.move(前文件名,后文件名)   # 重命名/移动,看后一个文件是文件夹还是文件名

shutil.make_archive(r'E:\159','zip','456')   # 把py文件目录的456压缩到E:\159,即E盘的根目录下159.zip

shutil.unpack_archive('159.zip',r'F:\159\158','zip')  # 把159.zip解压文件到F:\159\158,解压格式是zip.

6.1.4 json 模块

  1. 用法

    • son的本质(为着各程序间信息的传递而规定的一种通用格式)

      1. 本质是一个字符串(看起来像[],{},int/ bool )
      2. 最外层必须是list/dict
      3. 如果包含字符串,必须双引号--->其他程序字符串只识别双引号

      用法

      import json
      # 序列化,将python的值转换为json格式的字符串。
      # v = [12,3,4,{'k1':'v1'},True,'asdf']
      # v1 = json.dumps(v)
      # print(v1)
      json.dumps()    ---->返回值是json格式--->字符串
      
      
      # 反序列化,将json格式的字符串转换成python的数据类型
      # v2 = '["alex",123]'
      # print(type(v2))
      # v3 = json.loads(v2)
      # print(v3,type(v3))
      json.loads()   ---->返回值是python能识别的格式,外层一定是[]或{}
      
      

      python与json的对照表

          +-------------------+---------------+
          | Python            | JSON          |
          +===================+===============+
          | dict              | object        |
          +-------------------+---------------+
          | list, tuple       | array         |
          +-------------------+---------------+
          | str               | string        |
          +-------------------+---------------+
          | int, float        | number        |
          +-------------------+---------------+
          | True              | true          |
          +-------------------+---------------+
          | False             | false         |
          +-------------------+---------------+
          | None              | null          |
          +-------------------+---------------+
      
    • dumps 把python数据转换为json型的字符串 序列化

    • loads 把json字符串转换为python能够识别的数据类型 反序列还

    • 注意 :若字典或列表中有中文,序列化是想要保留中文显示

      v = {'k1':'alex','k2':'李杰'}   #e nsure_ascii=False
      
      import json
      val = json.dumps(v,ensure_ascii=False)
      print(val)
      
      
    • dump(内容,文件句柄) 有2个参数

      import json
      
      v = {'k1':'alex','k2':'李杰'}
      
      f = open('x.txt',mode='w',encoding='utf-8')
      val = json.dump(v,f)
      print(val)
      f.close()
      
      ## Json.dump()这个方法:它在底层做了两件事,一件事是将对象(列表)转换为字符串,第二件事是转换## 成功以后,将转换后的数据写入到文件中。
      
      
    • load

      import json
      
      v = {'k1':'alex','k2':'李杰'}
      
      f = open('x.txt',mode='r',encoding='utf-8')
      
      data = json.load(f)
      f.close()
      
      print(data,type(data))
      
      # 做了两件事,一件事:先来读取文件里的内容,第二件事是:将读取出来的内容进行数据类型的转换。
      

6.1.5 pickle 模块

  • json,优点:所有语言通用;缺点:只能序列化基本的数据类型 list/dict/int...

  • pickle,优点:python中所有的东西都能被他序列化(除了socket对象);缺点:序列化的内容只有python认识。

    import pickle
    
    ######################   dumps / loads  #######################3
    v = {1,2,3,4}
    val = pickle.dumps(v)
    print(val)
    data = pickle.loads(val)
    print(data,type(data))
    ########################  dump  / load  用法和json类似,这里不再赘述####
    
    ######################################################
    # 序列化 把其他数据类型转换成 str/bytes类型-->dump/dumps
    # 反序列化 str/bytes类型 转换回去         -->load/loads
       所有编程语言  json 所有的语言都支持
        # json格式 :
            # 1.所有的字符串都是双引号
            # 2.最外层只能是列表或者字典
            # 3.只支持 int float str list dict bool
            # 4.存在字典字典的key只能是str
            # 5.不能连续load多次
        # pickle 只支持python语言
            #  1.几乎所有的数据类型都可以写到文件中
            #  2.支持连续load多次
    

6.1.6time 和 datetime 模块

  1. time模块

    time.time() 时间戳,显示的是1970.1.1.凌晨0.00到现在经过的秒数,得到的是float数据类型

    time.sleep() 程序运行等待的秒数

    time.timezone : 属 性time.timezone是当地时区(未启动夏令时)距离格林威治的偏移秒数(>0,美洲;<=0大部分欧洲,亚洲,非洲) ,和电脑设置的逝去==时区有关

  2. datetime 模块

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import time
    from datetime import datetime,timezone,timedelta
    
    # ######################## 获取datetime格式时间 ##############################
    """
    v1 = datetime.now() # 当前本地时间
    print(v1)
    tz = timezone(timedelta(hours=7)) # 当前东7区时间
    v2 = datetime.now(tz)
    print(v2)
    v3 = datetime.utcnow() # 当前UTC时间
    print(v3)
    """
    
    # ######################## 把datetime格式转换成字符串 ##############################
    # v1 = datetime.now()
    # print(v1,type(v1))
    # val = v1.strftime("%Y-%m-%d %H:%M:%S")
    # print(val)
    
    # ######################## 字符串转成datetime ##############################
    # v1 = datetime.strptime('2011-11-11','%Y-%m-%d')
    # print(v1,type(v1))
    
    # ######################## datetime时间的加减 ##############################
    # v1 = datetime.strptime('2011-11-11','%Y-%m-%d')
    # v2 = v1 - timedelta(days=140)
    # date = v2.strftime('%Y-%m-%d')
    # print(date)
    
    # ######################## 时间戳和datetime关系 ##############################
    # ctime = time.time()
    # print(ctime)
    # v1 = datetime.fromtimestamp(ctime)
    # print(v1)
    
    # v1 = datetime.now()
    # val = v1.timestamp()
    # print(val)
    

6.1.7 collections 模块

# 调用模块,字典有序
from collections import OrderedDict

info  = OrderedDict()

# 有序字典
OrderDict()

# 字典的另一种写法
dict([(1,2),(3,4),(5,6)])   # dict化 列表套元组

# namedtuple,顾名思义,可命名元组
Course = namedtuple('Course',['name','price','teacher'])
python = Course('python',19800,'alex')
print(python)
print(python.name)
print(python.price)
# 创建一个类,这个类没有方法,所有属性的值都不能修改

# deque 双端队列

# defaultDict 默认字典,可以给字典的value设置一个默认值


6.1.8 hashlib 模块 摘要算法

  1. 将密码加密

    # import 模块名  # 调用py的内置模块,
    # PY调用hashlib模块对用户的密码进行加密,hashlib模块有很多种加密方式.这里选用MD5加密
    
    import hashlib
    
    def md5(arg):  # 加密函数   
        hash  = hashlib.md5('dengyxiin'.encode('utf-8'))    # 加盐,避免给黑客撞库得到密码.
        hash.update(arg.encode('utf-8'))
        return hash.hexdigest()     # 返回加密的md5,<----->t = hash.hexdigest();return t
    
    def register(user,pwd):  # 注册函数,参数为用户名和密码
        with open('data.txt','a',encoding='utf-8') as file:    #  追加模式写入文件
            file.write(user+'|'+md5(pwd)+'\n')  #用户名和密码用竖杠隔开,方便以后找寻
    
    def login(user,pwd):  # 登录函数
        with open('data.txt','r',encoding='utf-8') as file:    # 以只读模式打开文件,遍历文件,
            for line in file:
                line = line.strip()
                line = line.split('|')
                if user == line[0] and md5(pwd) == line[1]:    #遍历存储登录数据的文件,看能否比对的上.
                    return  True
    
    
  2. 密文验证

  3. 验证文件的一致性hashlib

    import hashlib
    hash = hashib.md5()
    hash.update()   # 无数次update,把大文件分割update进去即可.
    t = hash.hexdigest()
    print(t)
    
    
    # md5.update('hello'.encode())
    # md5.update(',wusir'.encode())
    # 46879507bf541e351209c0cd56ac160e
    # 46879507bf541e351209c0cd56ac160e  分批次update进去,最终结果相同
    

6.1.9 random模块(应用)

import random
random.unifom(1,5)  # 取1-5间的小数
val = random.choice(序列)   # -->从序列中随机抽取一个元素
val22 = ramdom.sample(序列,n)   # -->从序列中随机抽取n个元素
shuffle(序列)   # 打乱,洗牌

import random     # 调用随机数函数

def get_random_code(length=6):
    data = []
    for i in range(length):
        v = random.randint(65,90)  # 65-90对应的是ABC-----Z
        data.append(chr(v)
    return  ''.join(data)

code = get_random_code()
print(code)

6.1.10 getpass 模块

#  让密码在键入的时候隐藏
import getpass

pwd = getpass.getpass('请输入密码:')
if pwd == '123456789':
    print('输入正确')

    
import time
print(time.time())
time.sleep(2)    # --> 睡 2秒

6.2 模块分类

6.2.1内置模块

  1. random

  2. hashlib

  3. getpass

  4. time

  5. copy

  6. os

    • os.makedirs
    • os.path.join
    • rename 重命名
    • os.path.dirname
    • os.path.abspath
    • os.path.exists
    • os.stat('文件路径')
    • os.listdir
    • os.walk
  7. sys

    • sys.argv
    • sys.path
  8. shutil

  9. json

    • json 模块

      json的本质(为着各程序间信息的传递而规定的一种通用格式)

      1. 本质是一个字符串(看起来像[],{},int/ bool )
      2. 最外层必须是list/dict
      3. 如果包含字符串,必须双引号--->其他程序字符串只识别双引号

      用法

      import json
      # 序列化,将python的值转换为json格式的字符串。
      # v = [12,3,4,{'k1':'v1'},True,'asdf']
      # v1 = json.dumps(v)
      # print(v1)
      json.dumps()    ---->返回值是json格式--->字符串
      
      
      # 反序列化,将json格式的字符串转换成python的数据类型
      # v2 = '["alex",123]'
      # print(type(v2))
      # v3 = json.loads(v2)
      # print(v3,type(v3))
      json.loads()   ---->返回值是python能识别的格式,外层一定是[]或{}
      
      

      python与json的对照表

          +-------------------+---------------+
          | Python            | JSON          |
          +===================+===============+
          | dict              | object        |
          +-------------------+---------------+
          | list, tuple       | array         |
          +-------------------+---------------+
          | str               | string        |
          +-------------------+---------------+
          | int, float        | number        |
          +-------------------+---------------+
          | True              | true          |
          +-------------------+---------------+
          | False             | false         |
          +-------------------+---------------+
          | None              | null          |
          +-------------------+---------------+
      
  10. 内置模块补充

    • sys

6.2.2第三方模块

  1. 下载和安装

    pip的使用

    • # 把pip.exe 所在的目录添加到环境变量中。
      
      pip install 要安装的模块名称  # pip install requests
      
    • python36 -m pip install --upgrade pip 语句的使用

    • python3 -m pip install -U --force-reinstall pip 若pip更新失败,则如此

    • 网络不好一直抱超时错误的话可以换一个源,粘贴下边代码运行
      pip3 install xlrd -i http://pypi.douban.com/simple/ —trusted-host pypi.douban.com

      注意 : 这里的pip / pip3 都是自己定义的环境变量

    • 安装完成后,如果导入不成功。

      • 重启pycharm。
      • 安装错了。
  2. 你了解的第三方模块:

    • xlrd
    • requests

6.2.3自定义模块

  1. 自定义模块的导入

    xxxx.py # 自定义模块,实现某功能

    def func():
        print(123)  #实现打印123
    

    x2.py

    # 在x2.py中希望调用xxxx.py的函数
    ####1. xxxx.py 和  x2.py 在同一文件夹下
    import xxxx
    xxxx.func()
    
    ####2. 不在同一文件夹下
    import sys
    sys.path.append('xxxx.p文件的绝对路径')
    import xxxx
    xxxx.func()
    
    #####在cmd中运行x2.py文件
    python3 x2.py
    
    
    1. 模块和执行的py在同一目录,且需要调用很多函数

      # 在1.py文件中调用xxxx.py
      import xxxx
      xxxx.func()     #调用函数
      xxxx.func2()    #调用函数2
      
      
      
    2. 包和执行的py在同一目录

      from 包 import jd模块
      jd模块.func()    # 调用包内的jd模块的所有函数---
      
      from 包.jd模块 import func
      func()           #调用jd的func函数
      
      ################################
      from 包.jd模块 import func , show ,func2     #可以用都逗号连接
      func()
      show()
      func2() 
      
      
      #################################
      from 包.jd模块 import *  # 调用包.jd模块的全部功能
      
      
      • 模块和要执行的py文件在同一目录 且 需要 模块中的很多功能时,推荐用: import 模块
      • 其他推荐:from 模块 import 模块 模块.函数()
      • 其他推荐:from 模块.模块 import 函数 函数()
    3. 注意 : 要从其他路径调用模块时的用法

      import sys
      sys.path.append(r'D:\自建模块包\项目1模块')  # ---->把路径添加到python寻找模块时会去寻找的路径中,在调用模块
      import xxxx  # xxxx.py在'D:\自建模块包\项目1模块'目录下
      xxxx.func()
      
      # sys,path 本质是一个列表,是py解释器寻找模块时会去寻找的路径.path指定用于模块搜索路径的字符串列表。
      
    4. 模组调用

    5. import

      • import 模块1 模块1.函数()
      • import 模块1.模块2.模块3 模块1.模块2.模块3.函数()
    6. from xx import xxx

      • from 模块.模块 import 函数 函数()
      • from 模块.模块 import 函数 as f f()
      • from 模块.模块 import * 函数1() 函数2()
      • from 模块 import 模块 模块.函数()
      • from 模块 import 模块 as m m.函数()
      • 特殊情况:
        • import 文件夹 加载__init__.py
      • from 文件 import *
    7. 注意:文件和文件夹的命名不能是导入的模块名称相同,否则就会直接在当前目录中查找。

6.3 模块导入(重点)

6.3.1多次导入模块只加载一次--->单例模式

# 文件名  --> jd.py
print(123)


###################################
import jd # 第一次加载:会加载一遍jd中所有的内容。
import jd # 由已经加载过,就不在加载。   # 只打印一次123
print(456)


# 重加载 importilb.reload
import importlib
import jd
importlib.reload(jd)
print(456)   # 打印2次123  和456

**额外 : **通过模块导入的特性也可以实现单例模式

# jd.py
class Foo(object):
    pass

obj = Foo()

############################
# app.py
import jd
print(jd.obj)       # 单例模式

6.3.2日志操作loggin模块

  1. 作用:

    • 记录日志的
    • 用户 :查看操作记录
    • 程序员 :
      • 统计用
      • 故障排除
      • 记录错误,做代码优化
  2. 基本应用( 默认的,无法更改编码,win编码不同乱码,不推荐)

    import logging
    
    logging.basicConfig(
        filename='cmdb1.log',
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        level=logging.ERROR
    )
     #  默认的,无法更改编码,win编码不同乱码,不推荐
        
    logging.error(msg,exc_info=True)  # exc_info=True,打印错误日志是把栈信息打印出来
    
    # 使用方便
    # 不能实现 编码问题;不能同时向文件和屏幕上输出
    # logging.debug,logging.warning
    
  3. 日志处理的本质(Logger/FileHandler/Formatter)

    #复杂
        # 创建一个logger对象
        # 创建一个文件操作符
        # 创建一个屏幕操作符
        # 创建一个格式
    
        # 给logger对象绑定 文件操作符
        # 给logger对象绑定 屏幕操作符
        # 给文件操作符 设定格式
        # 给屏幕操作符 设定格式
        
        # 用logger对象来操作
    import logging
    
    logger = logging.Logger('xxxxxx', level=logging.ERROR)
    
    logger = logging.Logger('邓益新',level=10)
    # logger = logging.getLogger('boss')    ,无法设置level
    fh = logging.FileHandler('log.log','a',encoding = 'utf-8')
    sh = logging.StreamHandler()
    
    
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s',datefmt = '%Y-%m-%d %H-%M-%S',)
    fh.setFormatter(formatter)
    sh.setFormatter(formatter)
    
    logger.addHandler(fh)
    logger.addHandler(sh)
    
    logger.warning('message')
    
    # file_handler2 = logging.FileHandler('x2.log', 'a', encoding='utf-8')
    # fmt2 = logging.Formatter(fmt="%(asctime)s:  %(message)s")
    # file_handler2.setFormatter(fmt2)
    
    
    logger.error('你好')
    
    
  4. 推荐处理方式

    import logging
    
    file_handler = logging.FileHandler(filename='x3.log', mode='a', encoding='utf-8',)
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        handlers=[file_handler,],
        level=logging.ERROR
    )
    
    logging.error('你好')
    
    
  5. 日志处理 + 分割

    import logging
    from logging import handlers
    
    file_handler = handlers.TimedRotatingFileHandler(filename='x3.log', when='s', interval=5, encoding='utf-8')
    logging.basicConfig(
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p',
        handlers=[file_handler,],
        level=logging.ERROR
    )
    
    logging.error('你好')
    
    # when = ''取 S M H D W,不区分大小写
    
    
  6. 在应用日志时,如果想要保留异常的堆栈信息。

    logging.error('你好',exc_info=True)  # 即可
    

img新人上路,请多多批评指正img

posted on 2019-05-09 10:52  啊,那逝去的青春  阅读(205)  评论(0编辑  收藏  举报