基础常用模块
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
避免函数名,变量名冲突
a.py
def sayhi():
xxx
b.py
import a
def sayhi():
xxx
a.sayhi()
sayhi()
标准模块,内置模块 库 300
第三方模块 18万 pip install
自定义模块,自己写的
模块查找路径有关系
[‘D:\pyfile\路飞学城就业课程\第二模块-函数编程(极速版)\第二章-常用模块’,
‘D:\pyfile’,
‘D:\PyCharm-professional-2020.2.1\plugins\python\helpers\pycharm_display’, ‘C:\Users\82766\AppData\Local\Programs\Python\Python38\python38.zip’, ‘C:\Users\82766\AppData\Local\Programs\Python\Python38\DLLs’, 标准库
‘C:\Users\82766\AppData\Local\Programs\Python\Python38\lib’, ‘C:\Users\82766\AppData\Local\Programs\Python\Python38’, ‘C:\Users\82766\AppData\Local\Programs\Python\Python38\lib\site-packages’, 第三方模块
‘D:\PyCharm-professional-2020.2.1\plugins\python\helpers\pycharm_matplotlib_backend’]
pip install -i http://pypi.douban.com/simple/ alex_sayhi --trusted-host pypi.douban.com #alex_sayhi是模块名
代码如下:
import os
得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()
>>> os.getcwd()
'C:\\Users\\82766'
返回指定目录下的所有文件和目录名:os.listdir()
>>> os.listdir( 'Desktop')
['Adobe After Effects 2020.lnk', 'Adobe Audition 2020.lnk', 'Adobe Photoshop 2020.lnk', 'Adobe Premiere Pro 2020.lnk', 'desktop.ini', 'Google Chrome.lnk', 'WPS Office.lnk', '微信.lnk', '有道云笔记.lnk', '百度网盘.lnk', '金山打字通.lnk']
函数用来删除一个文件:os.remove()
删除多个目录:os.removedirs(r“c:\python”)
返回一个路径的目录名和文件名:os.path.split() os.path.split('/home/swaroop/byte/code/poem.txt') 结果:('/home/swaroop/byte/code', 'poem.txt')
检验给出的路径是否是一个文件:os.path.isfile()
检验给出的路径是否是一个目录:os.path.isdir()
判断是否是绝对路径:os.path.isabs()
检验给出的路径是否真地存在:os.path.exists()
获取路径名:os.path.dirname()
>>> os.path.dirname("D:\pyfile\路飞学城就业课程\第二模块-函数编程(极速版)\第二章-常用模块\ssh_remote_cmd.py")
'D:\\pyfile\\路飞学城就业课程\\第二模块-函数编程(极速版)\\第二章-常用模块'
获得绝对路径: os.path.abspath()
获取文件名:os.path.basename()
打印当前脚本所在路径,包含文件名
print(__file__)
代码如下(示例):
>>> import sys
>>> sys.platform 打印操作系统
'win32'
>>> sys.getdefaultencoding() 获取解释器默认编码
'utf-8'
>>> sys.getfilesystemencoding() 获取内存数据存到文件里的默认编码
'utf-8'
unix 1970 B C
ibm AIX unix
hp hp unix
oracle sun soloris
linux
windows
mac = unix
>>> import time
time.localtime([secs]):将一个时间戳转换为当前时区的struct_time
time.localtime()
>time.struct_time(tm_year=2020, tm_mon=10, tm_mday=19, tm_hour=15, tm_min=52, tm_sec=23, tm_wday=0, tm_yday=293, tm_isdst=0)
time.gmtime([secs]):gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time
time.gmtime()
>time.struct_time(tm_year=2020, tm_mon=10, tm_mday=19, tm_hour=7, tm_min=54, tm_sec=9, tm_wday=0, tm_yday=293, tm_isdst=0)
time.time():返回当前时间的时间戳
>1603094049.6242926
time.mktime(t):将一个struct_time转化为时间戳
t1 = time.gmtime()
print(t1)
time.struct_time(tm_year=2020, tm_mon=10, tm_mday=19, tm_hour=12, tm_min=51, tm_sec=39, tm_wday=0, tm_yday=293, tm_isdst=0)
print(time.mktime(t1))
1603083099.0
time.sleep(secs):线程推迟指定的时间运行,单位为秒
time.sleep(3)
time.asctime([t]):把一个表示时间的元组或者struct_time表示为这种形式:’Sun Oct 1 12:04:38 2019’。如果没有参数,将会将time.localtime()作为参数传入
time.asctime()
Mon Oct 19 15:57:06 2020
time.ctime([secs]):把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))
time.ctime()
Mon Oct 19 15:59:06 2020
time.strftime(format[, t]):把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()
>>> time.strftime("%Y-%m-%d %H:%M %p %j %z",time.localtime())
'2020-10-19 20:57 PM 293 +0800'
time.strptime(string[, format]):把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。
time.strptime("2020/04/01 19:30","%Y/%m/%d %H:%M")
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=1, tm_hour=19, tm_min=30, tm_sec=0, tm_wday=2, tm_yday=92, tm_isdst=-1)
1.datetime.datetime.now() 返回当前的datetime日期类型/显示当前时间
datetime.datetime.now()
>datetime.datetime(2020, 10, 19, 16, 20, 53, 427247)
2.>>> datetime.date.timetuple(datetime.date.today()) 转换成元组格式
time.struct_time(tm_year=2020, tm_mon=10, tm_mday=28, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=302, tm_isdst=-1)
3.datetime.date.fromtimestamp(322222) 把一个时间戳转为datetime日期类型
>>> datetime.datetime.fromtimestamp(123333)
datetime.datetime(1970, 1, 2, 18, 15, 33)
4.datetime.timedelta:表示时间间隔,即两个时间点之间的长度
>>> datetime.timedelta(days = 3)
datetime.timedelta(days=3)
>>> t1 - datetime.timedelta(days = 3)
datetime.datetime(2020, 10, 16, 16, 24, 17, 407845)
>>> t1 - datetime.timedelta(days = 3,minutes = 5)
datetime.datetime(2020, 10, 16, 16, 19, 17, 407845)
>>> t1 + datetime.timedelta(days = -3,minutes = 5)
datetime.datetime(2020, 10, 16, 16, 29, 17, 407845)
5.时间替换
>>> t1.replace(year = 2015,month = 10,minute = 1) 时间替换
datetime.datetime(2015, 10, 19, 16, 1, 17, 407845)
6.时区
import pytz
>>> import pytz
>>> pytz.all_timezones 查看所有时区
['Africa/Abidjan', 'Africa/Accra'
>>> pytz.timezone("Asia/Shanghai") 生成时区
<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>
>>> datetime.datetime.now(tz = pytz.timezone("Asia/Saigon")) 给时间配时区
datetime.datetime(2020, 10, 19, 15, 36, 42, 128838, tzinfo=<DstTzInfo 'Asia/Saigon' +07+7:00:00 STD>)
>>> random.randrange(1,10) #返回1-10之间的一个随机数,不包括10
>>> random.randint(1,10) #返回1-10之间的一个随机数,包括10
>>> random.randrange(0, 100, 2) #随机选取0到100间的偶数
>>> random.random() #返回一个0-1直间的随机浮点数
>>> random.choice('abce3#$@1') #返回一个给定数据集合中的随机字符
'#'
>>> random.sample('abcdefghij',3) #从多个字符中选取特定数量的字符
['a', 'd', 'b']
#生成随机字符串
import string
print("".join(random.sample(string.digits + string.ascii_lowercase,5)))
h8gsn
#洗牌
a = list(range(100))
random.shuffle(a)
print(a)
[96, 41, 37, 49, 45, 72, 5, 59, 48, 14, 90, 80, 69, 54, 55, 10, 32, 0, 24, 53, 76, 13, 9, 25, 92, 27, 70, 75, 56, 35, 18, 38, 6, 73, 21, 12, 28, 16, 86, 30, 84, 65, 52, 94, 63, 77, 71, 23, 88, 61, 50, 93, 51, 67, 44, 39, 74, 34, 87, 64, 83, 42, 3, 1, 31, 60, 85, 36, 58, 68, 20, 66, 17, 33, 98, 19, 47, 99, 22, 62, 81, 8, 4, 78, 89, 15, 29, 79, 97, 2, 11, 26, 40, 57, 91, 46, 7, 82, 95, 43]
pickle
import pickle
#dump写入文件
f = open("game.pkl","wb")
pickle.dump(d,f)
#dumps生成序列化字符串
d_dump = pickle.dumps(d) #序列化
print(d_dump)
b'\x80\x04\x95=\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x04alex\x94\x8c\x04role\x94\x8c\x06police\x94\x8c\x05blood\x94KL\x8c\x06weapon\x94\x8c\x04ak47\x94u.'
#load从文件加载
f = open("game.pkl","rb")
print(pickle.load(f))
b'\x80\x04\x95=\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x04alex\x94\x8c\x04role\x94\x8c\x06police\x94\x8c\x05blood\x94KL\x8c\x06weapon\x94\x8c\x04ak47\x94u.'
#loads 把序列化的字符串反向解析
print(pickle.loads(d_dump))
{'name': 'alex', 'role': 'police', 'blood': 76, 'weapon': 'ak47'}
json
import json
d = {
"name":"alex",
"role":"police",
"blood":76,
"weapon":"ak47"
}
alive_players = ["alex","jack","rain"]
f = open("game.json","w")
json.dump(d,f)
f = open("game.json","r")
json.load(f)
pickle vs json
pickle:
只支持python
支持python所有数据类型
class->object
function
datetime
json:
所有语言都支持
只支持python常规数据类型 str,int,dict,set,list,tuple
web fronted
html/js/css
function(){}
backed
python --json–>fronted dict
def nfname()
sdfdsgfd->2333333 碰撞
hfgrwerb->2333333
import hashlib
m = hashlib.md5()
m.update(b"hello alex")
print(m.hexdigest())
m.update("欢迎来到这里".encode("utf-8"))
# print(m.digest()) #消化
print(m.hexdigest())
m2 = hashlib.md5()
m2.update("hello alex欢迎来到这里".encode("utf-8"))
print(m.hexdigest())
拷贝文件
import shutil
shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
zipfile压缩&解压缩
import zipfile
# 压缩
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close()
# 解压
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall(path='.')
z.close()
匹配手机号
phone_list = re.search("[0-9]{11}",f.read()) #从全局找一个
print(phone_list)
常用的表达式规则:
‘.’ 默认匹配除\n之外的任意一个字符
>>> re.search(".","alex")
<re.Match object; span=(0, 1), match='a'>
打印
>>> re.search(".","alex").group()
'a'
‘^’ 匹配字符开头
>>> re.search("^alex","alex").group()
'alex'
>>> re.search("^alex","falex").group()
Traceback (most recent call last):
File "" , line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
‘$’ 匹配字符结尾
>>> re.search("^alex$","alex").group()
'alex'
>>> re.search("^alex$","alexop").group()
Traceback (most recent call last):
File "" , line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
** 匹配*号前的字符0次或多次,开头没有就返回空
>>> re.search("a*","ddd")
<re.Match object; span=(0, 0), match=''>
>>> re.search("a*","daaaddd")
<re.Match object; span=(0, 0), match=''>
>>> re.search("a*","adaaaddd")
<re.Match object; span=(0, 1), match='a'>
>>> re.search("a*","aaaadaaaddd")
<re.Match object; span=(0, 4), match='aaaa'>
‘+’ 匹配前一个字符1次或多次,可以到中间找
>>> re.search("a+","aaaadaaaddd")
<re.Match object; span=(0, 4), match='aaaa'>
>>> re.search("a+","daaaddd")
<re.Match object; span=(1, 4), match='aaa'>
>>> re.search("a+","dddd")
‘?’ 匹配前一个字符1次或0次,0次或1次
>>> re.search("a?","dddd")
<re.Match object; span=(0, 0), match=''>
>>> re.search("a?","aaadddd")
<re.Match object; span=(0, 1), match='a'>
‘{m}’ 匹配前一个字符m次
>>> re.search("a{4}","aaadddd")
>>> re.search("a{3}","aaadddd")
<re.Match object; span=(0, 3), match='aaa'>
‘{n,m}’ 匹配前一个字符n到m次
>>> re.search("a{1,2}","aaadddd")
<re.Match object; span=(0, 2), match='aa'>
>>> re.search("a{3,5}","aaadddd")
<re.Match object; span=(0, 3), match='aaa'>
>>> re.search("a{3,5}","aaaaaadddd")
<re.Match object; span=(0, 5), match='aaaaa'>
‘|’ 匹配|左或|右的字符
>>> re.search("abc|ABC","abcABC")
<re.Match object; span=(0, 3), match='abc'>
>>> re.search("abc|ABC","addggbcABdddfgC")
>>>
‘(…)’ 分组匹配
>>> re.search("(abc){2}a(123|45)", "abcabca456c")
<re.Match object; span=(0, 9), match='abcabca45'>
‘\A’ 只从字符开头匹配,相当于re.match(‘abc’,“alexabc”) 或^
>>> re.search("\Aabc","alexabc")
>>> re.search("\Aabc","abclexabc")
<re.Match object; span=(0, 3), match='abc'>
‘\Z’ 匹配字符结尾,同$
>>> re.search("abc\Z","dddabc")
<re.Match object; span=(3, 6), match='abc'>
[]
>>> re.search("[a-zA-Z0-9]{4}","jack")
<re.Match object; span=(0, 4), match='jack'>
‘\d’ 匹配数字0-9
>>> re.search("\d","ja455ck")
<re.Match object; span=(2, 3), match='4'>
>>> re.search("\d{3}","ja455ck")
<re.Match object; span=(2, 5), match='455'>
>>> re.search("\d+","ja455ck")
<re.Match object; span=(2, 5), match='455'>
‘\D’ 匹配非数字
>>> re.search("\D+","ja455ck")
<re.Match object; span=(0, 2), match='ja'>
>>> re.findall("\D+","ja455ck2523dggfd")
['ja', 'ck', 'dggfd']
>>> re.findall("\d+","ja455ck2523dggfd")
['455', '2523']
‘\w’ 匹配[A-Za-z0-9]
>>> re.findall("\w+","ja455ck25'>23dggfd")
['ja455ck25', '23dggfd']
‘\W’ 匹配非[A-Za-z0-9]
>>> re.findall("\W+","a*dvd+lombf/")
['*', '+', '/']
‘s’ 匹配空白字符、\t、\n、\r , re.search("\s+",“ab\tc1\n3”).group() 结果 ‘\t’
>>> re.findall("\s","a*\ndvd\t+lo\nmbf/")
['\n', '\t', '\n']
‘(?P…)’ 分组匹配 re.search("(?P[0-9]{4})(?P[0-9]{2})(?P[0-9]{4})
>>> re.search("([0-9]{3})([0-9]{3})([0-9]{4})",id_num)
<re.Match object; span=(0, 10), match='3714811993'>
>>> a = re.search("([0-9]{3})([0-9]{3})([0-9]{4})",id_num)
>>> a.groups()
('371', '481', '1993')
>>> a = re.search("(?P[0-9]{3})(?P[0-9]{3})(?P[0-9]{4})" ,id_num)
>>> a.groupdict()
{'province': '371', 'city': '481', 'birthday': '1993'}
re的匹配语法有以下几种:
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.findall("[0-9]{11}",phone)
re.split 以匹配到的字符当做列表分隔符
>>> import re
>>> re.split("[0-9]","alex3jack4rain6mike")
['alex', 'jack', 'rain', 'mike']
>>> re.split("[a-z]","alex3jack4rain6mike")
['', '', '', '', '3', '', '', '', '4', '', '', '', '6', '', '', '', '']
>>> re.findall("[0-9]","alex3jack4rain6mike")
['3', '4', '6']
取数字
>>> s='9-2*5/3+7/3*99/4*2998+10*568/14'
>>> re.split("[+\-\*/]",s)加\后面的语法不解释
['9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14']
re.sub 匹配字符并替换
>>> re.sub("abc","ABC","abcdefg")
'ABCdefg'
>>> re.sub("abc","ABC","abcdefgabc",count=2)
'ABCdefgABC'
>>> re.sub("[a-z]","0","abcdefg")
'0000000'
>>> re.sub("[a-z]","0","abcdefgAFB")
'0000000AFB'
re.fullmatch 全部匹配/精确匹配
>>> re.fullmatch("aaa","aaa")
<re.Match object; span=(0, 3), match='aaa'>
re.compile定义规则
>>> p = re.compile("[0-9]{11}")
>>> p
re.compile('[0-9]{11}')
>>> p.search("1222555555555")
<re.Match object; span=(0, 11), match='12225555555'>
Flags标志符:
re.I(re.IGNORECASE): 忽略大小写
>>> re.search("Efg","alexEFg",re.I)
<re.Match object; span=(4, 7), match='EFg'>
re.M(MULTILINE): 多行模式,改变’^’和’$’的行为
>>> re.search("^alex","alexjackrain")
<re.Match object; span=(0, 4), match='alex'>
>>> re.search("^alex","mack\nalexjackrain")
>
>>> re.search("^alex","mack\nalexjackrain",re.M)
<re.Match object; span=(5, 9), match='alex'>
>>> re.search("alex$","mack\nalex\njackrain",re.M)
<re.Match object; span=(5, 9), match='alex'>
re.S(DOTALL): 改变’.’的行为
>>> re.search(".","\n")
>>> re.search(".","\n",re.S)
<re.Match object; span=(0, 1), match='\n'>
re.X(re.VERBOSE) 可以给你的表达式写注释,使其更可读
a = re.compile(r"""\d + # the integral part
\. # the decimal point
\d * # some fractional digits""",
re.X)
b = re.compile(r"\d+\.\d*")
requirements.txt
1.生成requirement
pip freeze > requirements
2.安装requirements中的包
pip install -r requirements
这个文件存在的目的是:
方便开发者维护软件的包依赖。将开发过程中新增的包添加进这个列表中,避免在setup.py安装依赖时漏掉软件包。
方便读者明确项目使用了哪些Python包。
这个文件的格式是每一行包含一个包依赖的说明,通常是flask>=0.10这种格式,要求是这个格式能被pip识别,这样就可以简单的通过pip install -r requirements.txt来把所有Python包依赖都装好了。
一个文件夹管理多个模块文件,这个文件夹就被称为包:
一个包就是一个文件夹,但该文件夹下必须存在init.py 文件, 该文件的内容可以为空,int.py用于标识当前文件夹是一个包。
这个init.py的文件主要是用来对包进行一些初始化的,当当前这个package被别的程序调用时,init.py文件会先执行,一般为空, 一些你希望只要package被调用就立刻执行的代码可以放在init.py里。
在package路径下
init文件先执行
print("----welcome invoke my first pacckage-----")
跨目录导入
import sys
import os
base_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) #找到根目录
print(base_dir)
sys.path.append(base_dir) #将目录添加到查找路径
from logging_mod import log_test
def home_page():
print("welcome to applend")
print(log_test.sayhi)
home_page()
print("hahaha")
官方推荐方法
在manage中
print("---run my pro---")
from my_package import test
在test中
from logging_mod import log_test
def home_page():
print("welcome to applend")
print(log_test.sayhi)
home_page()
print("hahaha")
项目里创建个入口程序,整个程序调用的开始应该是从入口程序发起,这个入口程序一般放在项目的顶级目录
这样做的好处是,项目中的二级目录 apeland_web/views.py中再调用他表亲my_proj/settings.py时就不用再添加环境变量了。
原因是由于manage.py在顶层,manage.py启动时项目的环境变量路径就会自动变成….xxx/my_proj/这一级别
python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志
logging的日志可以分为 debug(), info(), warning(), error() and critical()5个级别
import logging
输出到屏幕
logging.warning("user [alex] attempted wrong password more than 3 times")
logging.critical("server is down")
WARNING:root:user [alex] attempted wrong password more than 3 times
CRITICAL:root:sever is down
写到文件
import logging
logging.basicConfig(filename='example.log',level=logging.INFO)
#输入只记录info及以上级别的日志
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
#定义格式
logging.basicConfig(filename="log_test.log",level=logging.DEBUG,
format='%(asctime)s:%(levelname)s#级别:%(filename)s:#打印文件名%(funcName)s:#哪个函数%(lineno)d:#哪行代码%(process)d#进程id %(message)s'#用户信息,datefmt='%Y-%m-%d %I:%M:%S %p'#时间)
同时向屏幕和文件输出日志
Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:
每个组件的主要功能
每个Logger可以附加多个Handler。
RotatingFileHandler方法
import logging
from logging import handlers
class IgnoreBackupLogFilter(logging.Filter):
"""忽略带db backup 的日志"""
def filter(self, record): #固定写法
return "db backup" not in record.getMessage()
#1.生成logger对象
logger = logging.getLogger("web")
logger.setLevel(logging.DEBUG)
# 1.1把filter对象添加到logger中
logger.addFilter(IgnoreBackupLogFilter())
#2.生成handler对象
ch = logging.StreamHandler()
fh = handlers.RotatingFileHandler(filename="web.log",maxBytes=10,backupCount=3)
#2.1把handler对象绑定到logger对象
logger.addHandler(ch)
logger.addHandler(fh)
#3生成formatter对象
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
#3.1把formatter对象绑定到handler对象
ch.setFormatter(console_formatter)
fh.setFormatter(file_formatter)
logger.info("test_log3")
logger.warning("test_log4")
logger.debug("test_log")
logger.debug("test log db backup")
TimedRotatingFileHandler方法
import logging
from logging import handlers
class IgnoreBackupLogFilter(logging.Filter):
"""忽略带db backup 的日志"""
def filter(self, record): #固定写法
return "db backup" not in record.getMessage()
#1.生成logger对象
logger = logging.getLogger("web")
logger.setLevel(logging.DEBUG)
# 1.1把filter对象添加到logger中
logger.addFilter(IgnoreBackupLogFilter())
#2.生成handler对象
ch = logging.StreamHandler()
fh = handlers.TimedRotatingFileHandler("web.log",when="S",interval=5,backupCount=3)
#2.1把handler对象绑定到logger对象
logger.addHandler(ch)
logger.addHandler(fh)
#3生成formatter对象
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
#3.1把formatter对象绑定到handler对象
ch.setFormatter(console_formatter)
fh.setFormatter(file_formatter)
logger.info("test_log3")
logger.warning("test_log4")
logger.debug("test_log")
logger.debug("test log db backup")
formatter 组件
日志的formatter是个独立的组件,可以跟handler组合
import logging
#1.生成logger对象
logger = logging.getLogger("web")
#设置整体日志级别
logger.setLevel(logging.DEBUG)
#2.生成handler对象
ch = logging.StreamHandler()
#设置日志级别
ch.setLevel(logging.INFO)
fh = logging.FileHandler("web.log")#输出到文件
#设置日志级别
fh.setLevel(logging.WARNING)
#2.1把handler对象绑定到logger对象
logger.addHandler(ch)
logger.addHandler(fh)
#3生成formatter对象
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
#3.1把formatter对象绑定到handler对象
ch.setFormatter(console_formatter)
fh.setFormatter(file_formatter)
#默认日志级别是warning
logger.debug("test_log")
#全局设置为debug后,console handler设置为info,如果输出的日志级别是debug,那就不会在屏幕上打印
filter 组件
如果你想对日志内容进行过滤,就可自定义一个filter
import logging
from logging import handlers
class IgnoreBackupLogFilter(logging.Filter):
"""忽略带db backup 的日志"""
def filter(self, record): #日志对象传进来,固定写法
return "db backup" not in record.getMessage()#不在日志里,返回true
#1.生成logger对象
logger = logging.getLogger("web")
logger.setLevel(logging.DEBUG)
# 1.1把filter对象添加到logger中
logger.addFilter(IgnoreBackupLogFilter())
#2.生成handler对象
ch = logging.StreamHandler()
# fh = handlers.RotatingFileHandler(filename="web.log",maxBytes=10,backupCount=3)
fh = handlers.TimedRotatingFileHandler("web.log",when="S",interval=5,backupCount=3)
# fh = logging.FileHandler("web.log")
#2.1把handler对象绑定到logger对象
logger.addHandler(ch)
logger.addHandler(fh)
#3生成formatter对象
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(lineno)d - %(message)s')
#3.1把formatter对象绑定到handler对象
ch.setFormatter(console_formatter)
fh.setFormatter(file_formatter)
logger.info("test_log3")
logger.warning("test_log4")
logger.debug("test_log")
logger.debug("test log db backup")
基础常用模块