python模块简述

time模块

import time
print(time.time())#获取时间戳 浮点数
print(time.sleep(2))#睡眠,阻塞
print(time.strftime('%Y-%m-%d %H:%M:%S'))#时间显示格式,页面显示的格式
print(time.gmtime())#结构化时间,元祖的形式(命名元祖),可以根据索引和元素进行查找
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=25, tm_hour=8, tm_min=10, tm_sec=50, tm_wday=3, tm_yday=206, tm_isdst=0)
#time.localtime获取的是当地时间
	# print(time.gmtime()[0])
	# print(time.gmtime().tm_year)
#将时间戳转换成字符串时间
print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(1564028611.631374)))
#将字符串时间转换成时间戳
print(time.mktime(time.strptime("2024-3-16 12:30:30","%Y-%m-%d %H:%M:%S")))
---------------------------------------
重点:
# time重点:
time.time()
time.sleep() 
time.gmtime() / time.localtime() #
time.strftime("格式化","结构化时间") #
time.strptime("字符串","格式化")
time.mktime()
****************************************************************

datatime模块

print(type(datetime.now()))获取当前时间,获取的是一个对象
print(datetime(2019,5,21,15,14,00) - datetime(2019,5,20,14,20,00))计算时间差
# 将当前时间转化成时间戳
t = datetime.now()
print(t.timestamp())
-----------------------------------------
# 将时间戳转化成当前时间
import time
print(datetime.fromtimestamp(15000000000))
-----------------------------------------------------
# 将字符串转成对象
print(type(datetime.strptime("2019-10-10 22:23:24","%Y-%m-%d %H:%M:%S")))
-----------------------------------------------------
# 将对象转成字符串
print(str(datetime.now()))
print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
------------------------------------------------------
# datetime加减
print(datetime.now() + timedelta(hours=30 * 24 * 12))
print(datetime.now() - timedelta(hours=30 * 24 * 12))
***********************************************************
# datatime模块
import datetime
now_time = datetime.datetime.now()  # 现在的时间
# 只能调整的字段:weeks days hours minutes seconds
print(datetime.datetime.now() + datetime.timedelta(weeks=3)) # 三周后
print(datetime.datetime.now() + datetime.timedelta(weeks=-3)) # 三周前
print(datetime.datetime.now() + datetime.timedelta(days=-3)) # 三天前
print(datetime.datetime.now() + datetime.timedelta(days=3)) # 三天后
print(datetime.datetime.now() + datetime.timedelta(hours=5)) # 5小时后
print(datetime.datetime.now() + datetime.timedelta(hours=-5)) # 5小时前
print(datetime.datetime.now() + datetime.timedelta(minutes=-15)) # 15分钟前
print(datetime.datetime.now() + datetime.timedelta(minutes=15)) # 15分钟后
print(datetime.datetime.now() + datetime.timedelta(seconds=-70)) # 70秒前
print(datetime.datetime.now() + datetime.timedelta(seconds=70)) # 70秒后

current_time = datetime.datetime.now()
# 可直接调整到指定的 年 月 日 时 分 秒 等

print(current_time.replace(year=1977))  # 直接调整到1977年
print(current_time.replace(month=1))  # 直接调整到1月份
print(current_time.replace(year=1989,month=4,day=25))  # 1989-04-25 18:49:05.898601

# 将时间戳转化成时间
print(datetime.fromtimestamp(1232132131))  # 2009-01-17

random模块

print(random.random())#在0~1之间随机生成一个浮点数
print(random.uniform(0,10))#在0~10时间随机生成一个浮点数,可以指定范围
print(random.randint(1,10))#随机生成一个整数,可以指定范围
print(random.randrange(1,5,2))#起始终止步长,生成一个数字
print(random.chioce([1,2,3,4,5,6]))#随机选择一个元素
print(random.chioces([1,2,3,4,5,6,7]),k=2)#随机选择两个元素,会有重复的
print(random.sample((1,2,3,4,5,6,7,8)),k=2)#随机选择两个元素,不会有重复的,除非只有两个
print(random.shuffle(lst))#打乱顺序
*************************************************
>>> import random
#随机小数
>>> random.random()     # 大于0且小于1之间的小数
0.7664338663654585
>>> random.uniform(1,3) #大于1小于3的小数
1.6270147180533838

#随机整数
>>> random.randint(1,5)  # 大于等于1且小于等于5之间的整数***
>>> random.randrange(1,10,2) # 大于等于1且小于10之间的奇数***

#随机选择一个返回
>>> random.choice([1,'23',[4,5]])  # #1或者23或者[4,5]
#随机选择多个返回,返回的个数为函数的第二个参数***
>>> random.choices([1,2,3,4],k=2) # 选择两个元素,会有重复,可控制元素个数***
>>> random.sample([1,'23',[4,5]],k=2) # #列表元素任意2个组合,不会重复(原列表有重复就会出现重复),可控制元素个数***
[[4, 5], '23']

#打乱列表顺序
>>> item=[1,3,5,7,9]
>>> random.shuffle(item) # 对原列表打乱次序
>>> item
[5, 1, 3, 7, 9]
>>> random.shuffle(item)
>>> item
[5, 9, 7, 1, 3]

序列化模块

  • json

    1.dumps loads
            lit = [1,22,3,3,45]
            print(json.dumps(lit),type(json.dumps(lit)))
            str_lst = json.dumps(lit)
            lst = json.loads(str_lst)
            print(lst,type(lst))
    
            dumps 将对象转换(序列化)成字符串
            loads 将字符串转换(反序列化)成对象
    
            dic = {'username':'宝元'}
            str_dic = json.dumps(dic)  # 序列化
            str_dic = json.dumps(dic,ensure_ascii=False)  # ensure_ascii=False 关闭ascii码
            print(str_dic,type(str_dic))
            dic1 = json.loads(str_dic)  # 反序列化
            print(dic1,dic1["username"])
    
    2.dump load
            import json
            lit = [1,22,3,3,45]
            同时写多个内容 进行序列化
            lst = [1,2,3,4,56,]
            f = open("info","w",encoding="utf-8")
            f.write(json.dumps(lst) + "\n")
            f.write(json.dumps(lst) + "\n")
            f.write(json.dumps(lst) + "\n")
            f.write(json.dumps(lst) + "\n")
            f.write(json.dumps(lst) + "\n")
            f.close()
    
            dump: 将对象转换(序列化)成字符串,写入文件
            load: 将文件中字符串转换(反序列)成对象
    
            同时读多个内容进行反序列
            f1 = open("info","r",encoding="utf-8")
            for i in f1:
                l = json.loads(i)
                print(l)
            f1.close()
    
    
  • pickle模块

    pickle 序列化 - nb(python所有对象进行转换)
    python自带的(只有python可以用)
    两组4个方法:
    1. dumps loads
            import pickle
    
            lst = [12,3,4,5,768]
            t_list = pickle.dumps(lst) # 转换成类似字节
            print(t_list)
            print(pickle.loads(t_list)[-1])
    
            dic = {"user":"郭宝元"}
            t_list = pickle.dumps(dic) # 转换成类似字节
            print(t_list)
            print(pickle.loads(t_list))
    
            def func():
                print(111)
    
            import json
            fun = json.dumps(func)
            print(fun)
    
            fun = pickle.dumps(func)
            print(fun)
            pickle.loads(fun)()
    
    2. dump  load
    import pickle
    dic = {"usern":"baoyuian"}
    dic = {"usern":"宝元"}
    pickle.dump(dic,open("info","wb"))
    print(pickle.load(open("info","rb")))
    
    import pickle
    dic = {"user":"123"}
    pickle.dump(dic,open("info","ab"))
    
    import pickle
    dic = {"1":2}
    f = open("info","wb")
    s = "\n".encode("utf-8")
    f.write(pickle.dumps(dic)+ s)
    f.write(pickle.dumps(dic)+ s)
    f.write(pickle.dumps(dic)+ s)
    f.close()
    
    f1 = open("info","rb")
    for i in f1:
        print(pickle.loads(i))
    
    推荐使用json
      json是各种语言通用的
    
    

os模块

  • os模块是程序员通过python向操作系统发送指令的交互接口

    import os
    #工作目录
    print(os.getcwd())#获取当前的工作路径
    print(os.chdir())#修改工作路径
    print(os.curdir)
    print(os.pardir)
    #文件夹
    print(os.mkdir('aaa'))
    print(os.rmdir('aaa'))
    print(os.makedirs('aaa/bbb/ccc'))
    print(os.removedirs('aaa/bbb/ccc'))
    print(os.listdir('E:\python24期笔记\day17'))
    #文件相关
    print(os.rename('aa.txt','bb.txt'))#修改文件名
    print(os.remove('sss'))#删除文件
    #路径相关
    print(os.path.abspath('F:\oldboy\day17\os模块.py'))#获取绝对路径
    print(os.path.dirname('F:\oldboy\day17\os模块.py'))#获取文件夹路径
    print(os.path.basename('F:\oldboy\day17\os模块.py'))#获取文件目录
    print(os.path.split('F:\oldboy\day17\os模块.py'))#对文件夹和文件分割
    print(os.path.isabs('F:\oldboy\day17\os模块.py'))#判断是不是绝对路径
    print(os.path.isdir('F:\oldboy\day17'))#判断是不是一个目录
    print(os.path.isfile('F:\oldboy\day17\os模块.py'))#判断是不是一个文件名
    print(os.path.exists('F:\oldboy\day17\os模块.py'))#判断路径存不存在
    print(os.path.join())#拼接路径
    os.path.getatime()#查看文件的最后访问时间
    os.path.getmtime()#查看文件的最后修改时间
    os.path.getctime()#文件的创建时间
    os.path.getsize()#路径的字节大小,按照kb返回
    

hashlib模块

md5,sha1,sha256,sha512
1.只要明文相同密文就是相同的
2.只要明文不相同密文就是不相同的
3.不能反逆(不能解密) -- md5中国人破解了
加密:
    1.加密的内容
    2.将要加密的内容转成字节
#最常用是的md5,平时加密的时候使用sha1
#加固定盐
import hashlib
md5 = hashlib.md5("常鑫".encode("utf-8"))
md5.update("alex123".encode("utf-8"))
print(md5.hexdigest())

md5 = hashlib.md5()
md5.update("alex123".encode("utf-8"))
print(md5.hexdigest())

#动态加盐
user = input("username:")
pwd = input("password")

import hashlib
md5 = hashlib.md5(user.encode("utf-8"))
md5.update(pwd.encode("utf-8"))
print(md5.hexdigest())

md5 = hashlib.md5()
md5.update(pwd.encode("utf-8"))
print(md5.hexdigest())

#767db14ed07b245e24e10785f9d28e29

f = open(r"F:\s24\day17\python-3.6.6-amd64.exe","rb")
import hashlib
md5 = hashlib.md5()
md5.update(f.read())
print(md5.hexdigest())

ss = "baoyuanalextaibai"
s = "baoyuan"
s1 = "alex"
s2 = "taibai"
import hashlib
md5 = hashlib.md5()
md5.update(ss.encode("utf-8"))
print(md5.hexdigest())


md5 = hashlib.md5()
md5.update(s.encode("utf-8"))
md5.update(s1.encode("utf-8"))
md5.update(s2.encode("utf-8"))
print(md5.hexdigest())

#节省内存

f = open(r"F:\s24\day17\python-3.6.6-amd64.exe","rb")
import hashlib
md5 = hashlib.md5()
while True:
    msg = f.read(1024)
    if msg:
        md5.update(msg)
    else:
        print(md5.hexdigest())
        break

collections模块

collections模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

1.namedtuple: 生成可以使用名字来访问元素内容的tuple

2.deque: 双端队列,可以快速的从另外一侧追加和推出对象

3.Counter: 计数器,主要用来计数

4.OrderedDict: 有序字典

5.defaultdict: 带有默认值的字典
====================================================================================
#namedtuple
我们知道tuple可以表示不变数据,例如,一个点的二维坐标就可以表示成:

p = (1, 2)
但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。

这时,namedtuple就派上了用场:

from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
print(p)
结果:Point(x=1, y=2)

类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:

namedtuple('名称', [属性list]):
Circle = namedtuple('Circle', ['x', 'y', 'r'])
deque
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
----------------------------------------------------------------------------------
#deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:

from collections import deque
q = deque(['a', 'b', 'c'])
q.append('x')
q.appendleft('y')
q
deque(['y', 'a', 'b', 'c', 'x'])
deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
------------------------------------------------------------------------
#OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。

如果要保持Key的顺序,可以用OrderedDict:

from collections import OrderedDict
d = dict([('a', 1), ('b', 2), ('c', 3)]) # 另一种定义字典的方式
print(d)
# 结果:
{'a': 1, 'c': 3, 'b': 2}

od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print(od)
# 结果:
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:

>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的顺序返回
['z', 'y', 'x']
--------------------------------------------------------------------------
#defaultdict
有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。

即: {'k1': 大于66 , 'k2': 小于66}

li = [11,22,33,44,55,77,88,99,90]
result = {}
for row in li:
    if row > 66:
        if 'key1' not in result:
            result['key1'] = []
        result['key1'].append(row)
    else:
        if 'key2' not in result:
            result['key2'] = []
        result['key2'].append(row)
print(result)

from collections import defaultdict
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = defaultdict(list)

for value in  values:
    if value>66:
        my_dict['k1'].append(value)
    else:
        my_dict['k2'].append(value)
使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:

from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
 # key1存在
print(dd['key1'])
dd['key2'] # key2不存在,返回默认值
print(dd['key2'])
-------------------------------------------------
#Counter
Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。

c = Counter('abcdeabcdabcaba')
print c
输出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})

re模块

s='lijie_李杰_l\tlilililijiee123@'
#\w匹配字母数字,下划线包括中文
print(re.findall('\w',s))
#\W匹配非字母数字,下划线包括中文
print(re.findall('\W',s))
#\s匹配任意空格,换行符,制表符
print(re.findall('\s',s))
#\S匹配非任意空格,换行符,制表符
print(re.findall('\S',s))
#\d匹配数字
print(re.findall('\d',s))
#\D匹配非数字
print(re.findall('\D',s))
#A或^匹配开头的内容
print(re.findall('\Alijie',s))
print(re.findall('^lijie',s))
#\Z或$匹配结尾的内容
print(re.findall('123@\Z',s))
print(re.findall('123@$',s))
#\n \t 匹配换行符和制表符
print(re.findall('\n',s))
print(re.findall('\t',s))
#.匹配任意一个内容(换行符除外)
print(re.findall('l.j',s))
print(re.findall('l.j',s,re.DOTALL))#.匹配任意时,可以匹配所有
#[]指定匹配的范围
print(re.findall('[A-Za-z0-9]',s))
#[^]匹配指定范围之外的
print(re.findall('[^a-z]',s))
#*匹配0个或多个内容
print(re.findall('li*',s))#贪婪匹配
#+匹配1个或多个内容
print(re.findall('li',s))#贪婪匹配
#?匹配0个或一个内容
print(re.findall('li?',s))
#{}重复匹配指定字符几次
print(re.findall('l{1}',s))
#{1,6}指定重复匹配指定字符的次数范围
print(re.findall('l{1,6}',s))
#|或者
print(re.findall('li|jie',s))
#()匹配括号里的内容
print(re.findall('l(.+?)j',s))
print(re.findall('l(?:.+?)l',s))#()匹配时?:可以将括号外面的一起返回
#search匹配一个,匹配到返回的是一个对象,查看元素用group()方法
print(re.search('li',s))
#match从字符串的开头查找,返回一个对象,查看元素用group()方法
print(re.match('li',s))
#finditer返回一个迭代器
a=re.finditer('\w','你好世界')
print(next(a).group())#用group查看值
#split分割
print(re.split('l',s))
#sub替换
print(re.sub('li','哈哈','lijieljie'))
#?P分组起名
print(re.findall('(?P<aaa>\w)jie',s).group('aaa'))
#\.转义
# 匹配所有的数字(包含小数包含负号)
# print(re.findall("-?\d+\.\d+|-?\d+",s))

元字符 匹配内容
\w 匹配字母(包含中文)或数字或下划线
\W 匹配非字母(包含中文)或数字或下划线
\s 匹配任意的空白符
\S 匹配任意非空白符
\d 匹配数字
\D p匹配非数字
\A 从字符串开头匹配
\z 匹配字符串的结束,如果是换行,只匹配到换行前的结果
\n 匹配一个换行符
\t 匹配一个制表符
^ 匹配字符串的开始
$ 匹配字符串的结尾
. 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中的字符的所有字符
* 匹配0个或者多个左边的字符。
+ 匹配一个或者多个左边的字符。
匹配0个或者1个左边的字符,非贪婪方式。
精准匹配n个前面的表达式。
匹配n到m次由前面的正则表达式定义的片段,贪婪方式
a|b 匹配a或者b。
() 匹配括号内的表达式,也表示一个组

模块和包

只要文件夹下含有__init__.py文件就是一个包,包是干什么的呢?

回想一下,之前我们没有学习模块的时候将一个整体的功能写入到文件中,为了能够充分的将某个功能进行重用 我们使用了模块,但是慢慢的模块就会越来越多.我们想提高程序的结构性可维护性,就使用包将模块进行统一管理

包能够管理多个模块,我们想要使用包里的模块怎么办呢?

使用import 和from xx import xx 现有如下结构

bake            

    ├── __init__.py       

    ├── api               

        ├── __init__.py

        ├── policy.py

        └── versions.py

  ├── cmd             

    ├── __init__.py

    └── manage.py

  └── db                

      ├── __init__.py

      └── models.py
我们在bake同级创建一个test.py进行导入policy.py 我们使用模块的import的时候只能将api添加到sys.path的路劲中,我们来看看包使用import导入

import bake.api.policy
bake.api.policy.get()
导入的太长了下边使用的时候还需要在重复写一遍,我们可以使用as起别名

import bake.api.policy as p
p.get()
这样的操作只支持包,普通的文件夹无效,有人一定在想我把bake拿过来然后一层一层的打开那拿工具就可以了

import bake
bake.api.policy.get()
不好使,这样导入是只将policy导入了,有人想怎么将api包下的模块全部导入不要急,先说单独导入的方式

咱们能够使用import进行导入,在来看看from的导入方式

from bake.api import policy
policy.get()
from bake import api
print(api.versions.name)
还是不好使,通过这两个我们能够感觉都导入的时候指定要导入的内容,不能再导入后在进行开箱子

我们现在说了单独导入一个模块,现在来说道说道怎么导入某个包下的所有模块,想要导入某个包下的所有的模块 我们就需要在包中的__init__.py做点手脚

bake包下的__init__.py
from . import api
.是当前路径,因为from的时候不能空着

api包下的__init__.py
from . import policy
我们将包下的__init__配置好,然后在test.py进行导入

import bake
bake.api.policy.get()
又好使了,这是为什么呢?我们import导入bake这个包,因为bake是一个文件夹不能进行任何操作,就让__init__.py代替它 去将api这包中的模块导入,api也是一个文件夹不能操作就需要让api下边的__init__.py去找api下边的两个模块

这个和公司的上下级关系一样,打比方现在test.py就是一个ceo要和policy这个小员工谈话,ceo先把这个想法人事经理,人事经理就是 bake这个包,人事经理通知人事让人事查找一下policy在那个部门,人事查到后通知部门的负责人,部门的负责人在通知部门的主管,主管告诉policy这个员工, 说ceo要找你,部门的主管带着policy去找人事,人事带着policy,人事然后在带着policy去找ceo.最后成功的和ceo进行了一番交流

如果在传达的时候中间一个环节忘记传递了,policy就不知道ceo在找他,ceo等了好久不来ceo就生气报错了

使用的时候需要注意: 有的同学,想在policy文件中导入versions就是直接使用import,在policy文件使用没有问题,很美,很高兴.但是在test.py执行的时候就会报错 因为我们在test.py中执行的import versions 相当于在test.py文件进行查找,肯定不会找到,我们需要在policy文件中向sys.path添加了当前的路劲就可以了 具体操作如下:

import os
import sys
sys.path.insert(os.path.dirname(__file__)
__file__获取的是当前文件的路径,这样我们就能在test中正常使用了,我们使用from也能够将某个包下所有的模块全都导入 比如我们现在想将cmd包下的所有的模块导入需要在bake包下的__init__.py进行设置

from . import *
我们需要在api包下设置__init__.py

__all__ = ["policy","versions"]
或
from . import policy
from . import versions
我们需要在db包下设置__init__.py

__all__ = ["models"]
或
from . import models
我们需要在cmd包下设置__init__.py

__all__ = ["manage"]
或
from . import manage
以上两种推荐使用下from . import manage 灵活,可读性高

test.py调用如下:

from bake.api import *
print(versions.name)
policy.get()

from bake.db import *
models.register_models(123)

from bake.cmd import *
print(manage.name)
在使用import有个注意点,python2中如果import包,没有__init__.py文件就会报错 python3 import没有__init__.py文件的包不会报错 from 包 import 包或者模块(在import后边不能在进行.操作)

路径: 绝对路径:从最外层(bake)包.查找的就是绝对路径 相对路径:.就是相对路径, ..是上一级目录 例如:我们在bake/api/version.py中想要导入bake/cmd/manage.py

# 绝对路径:
from bake.cmd import manage
manage.main()

#相对路径:
from ..cmd import manage
manage.main()
注意在使用相对路径的时候一定要在于bake同级的文件中测试 我们需要在和bake同级的test.py中测试

from bake.cmd import manage

logging日志模块

其实每个软件都是有错误日志的,开发人员可以通过错误日志中的内容对他的程序进行修改

这只是一种应用场景,有的还会将日志用于交易记录.比如你给我转账应该做记录吧,

我们使用的信用卡,每消费的一笔都会记录,我们来看看这个日志怎么用?

我们先来看一下函数式简单配置

import logging  
logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message')
默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING

(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),

默认的日志格式为日志级别:Logger名称:用户输出消息。

我们自己用函数写的这个可以正常使用但是不够灵活,我们看看这个灵活的

灵活配置日志级别,日志格式,输出位置:

import logging  
logging.basicConfig(level=logging.DEBUG,  
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
                    datefmt='%a, %d %b %Y %H:%M:%S',  
                    filename='/tmp/test.log',  
                    filemode='w')  

logging.debug('debug message')  
logging.info('info message')  
logging.warning('warning message')  
logging.error('error message')  
logging.critical('critical message')
basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:

filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置记录日志的级别
stream:用指定的stream创建StreamHandler。可以指定输出到
sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
format参数中可能用到的格式化串:

%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息
logger对象配置

import logging

logger = logging.getLogger()
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log',encoding='utf-8') 

# 再创建一个handler,用于输出到控制台 
ch = logging.StreamHandler() 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

fh.setLevel(logging.DEBUG)

fh.setFormatter(formatter) 
ch.setFormatter(formatter) 
logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 
logger.addHandler(ch) 

logger.debug('logger debug message') 
logger.info('logger info message') 
logger.warning('logger warning message') 
logger.error('logger error message') 
logger.critical('logger critical message')
logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过

fh.setLevel(logging.Debug)单对文件流设置某个级别。
================================================================
import logging

logger = logging.getLogger()
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log',encoding='utf-8')

# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

fh.setLevel(logging.DEBUG)

fh.setFormatter(formatter)
ch.setFormatter(formatter)
logger.addHandler(fh) #logger对象可以添加多个fh和ch对象
logger.addHandler(ch)

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

logging日志旗舰版

"""
logging配置
"""

import os
import logging.config

# 定义三种日志输出格式 开始

standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'

# 定义日志输出格式 结束

logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录

logfile_name = 'all2.log'  # log文件名

# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
    os.mkdir(logfile_dir)

# log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name)

# log配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
    },
    'filters': {},
    'handlers': {
        #打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        #打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            'formatter': 'standard',
            'filename': logfile_path,  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置
        '': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)传递
        },
    },
}


def load_my_logging_cfg():
    logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
    logger = logging.getLogger(__name__)  # 生成一个log实例
    logger.info('It works!')  # 记录该文件的运行状态

if __name__ == '__main__':
    load_my_logging_cfg()

posted @ 2019-10-03 18:21  luckinlee  阅读(123)  评论(0编辑  收藏  举报