杂(七)
字符串格式化
一、方式(2种)
python官方文档链接:https://www.python.org/dev/peps/pep-3101/
1、百分号方式:%
%[(name)][flags][width].[precision]typecode
1.1、占位符:%s、%d
s = '哈哈哈哈哈哈 %s 张三 %d' %('张三',21) print(s) #打印结果:哈哈哈哈哈哈 张三 张三 21
1.2、(name)可选,用于选择指定的key
解析:对于占位符%s、%d 命名,后面通过字典的方式将name与%s结合起来
s = '哈哈哈哈哈哈 %(name)s 张三 %(age)d' %{'name':'张三','age':21} print(s) #打印结果:哈哈哈哈哈哈 张三 张三 21
1.3、flags(对齐):可选,可供选择的值有 ;一般与width(宽度)一起才可以起到作用
+ 右对齐;正数前加正号,负数前加负号;
- 左对齐;正数前无符号,负数前加负号;
空格 右对齐;正数前加空格,负数前加负号;
0 右对齐;正数前无符号,负数前加负号;用0填充空白处
解析:一般与width一起使用,如下代码中的10代表的是占10个占位符,但10个占位符只有6位,所以右对齐,并且是已空格的方式补足10位
s = '前面%(name)+10s后面' %{'name':'10个占位符'} print(s) #打印结果:前面 10个占位符后面
#+号,正数前面加+号 s = '前面%(name)+10s后面 %(age)+10d' %{'name':'10个占位符','age':123} print(s) #打印结果:前面 10个占位符后面 +123
1.4、.precision:可选,小数点后保留的位数
如下代码,只保留2位小数,并且遵循的是四舍五入的原则
s = '前面%(name)+10s后面 %(age)+10d %(p).2f' %{'name':'10个占位符','age':123,'p':1.246783} print(s) #打印结果:前面 10个占位符后面 +123 1.25
1.5、typecode:必选
s,获取传入对象的__str__方法的返回值,并将其格式化到指定位置
(可忽略)r,获取传入对象的__repr__方法的返回值,并将其格式化到指定位置
c,整数:将数字转换成其unicode对应的值,10进制范围为 0 <= i <= 1114111(py27则只支持0-255);字符:将字符添加到指定位置
o,将整数转换成 八 进制表示,并将其格式化到指定位置
x,将整数转换成十六进制表示,并将其格式化到指定位置
d,将整数、浮点数转换成 十 进制表示,并将其格式化到指定位置
e,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写e)
E,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写E)
f, 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位)
F,同上
g,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是e;)
G,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是E;)
%,当字符串中存在格式化标志时,需要用 %%表示一个百分号
当格式化时,字符串中出现占位符%s、%d,需要用%%才能在输出的时候输出%,不然会报错
当格式化时,字符串中没有出现过占位符,可以直接用%来表示%输出
s = "前置 %c------%o=======%x --------%e========%E==========%g------%g" %(65,15,15,1000,20000000,100,1000000000) print(s) #打印结果: ''' 前置 A------17=======f --------1.000000e+03========2.000000E+07==========100------1e+09 ''' s1 = '前置 %' print(s1) #打印结果: ''' 前置 % ''' s2 = '前置 %s %%' %('哈哈') print(s2) #打印结果: ''' 前置 哈哈 % '''
2、format方式
2.1、格式汇总:[[fill]align][sign][#][0][width][,][.precision][type]
2.2、fill 【可选】,空白处填充的字符
2.3、align 【可选】 对齐方式(需要配合width使用)
<,内容左对齐
>,内容右对齐(默认)
=,内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
^,内容居中
2.4、sign 【可选】,有无符号数字--只对数字有效
+,正号加正,负号加负;
-,正号不变,负号加负;
空格 ,正号空格,负号加负;
2.5、# 【可选】对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显
2.6、0 【可选】第0个参数
2.6、, 【可选】为数字添加分隔符,如:1,000,000
2.7、width 【可选】格式化位所占宽度
2.8、.precision 【可选】小数位保留精度
2.9、type 【可选】格式化类型
传入” 字符串类型 “的参数
s,格式化字符串类型数据
空白,未指定类型,则默认是None,同s
传入“ 整数类型 ”的参数
b,将10进制整数自动转换成2进制表示然后格式化(format方式支持,%的方式不支持转换成二进制)
c,将10进制整数自动转换为其对应的unicode字符
d,十进制整数
o,将10进制整数自动转换成8进制表示然后格式化;
x,将10进制整数自动转换成16进制表示然后格式化(小写x)
X,将10进制整数自动转换成16进制表示然后格式化(大写X)
传入“ 浮点型或小数类型 ”的参数
e, 转换为科学计数法(小写e)表示,然后格式化;
E, 转换为科学计数法(大写E)表示,然后格式化;
f , 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
F, 转换为浮点型(默认小数点后保留6位)表示,然后格式化;
g, 自动在e和f中切换
G, 自动在E和F中切换
%,显示百分比(默认显示小数点后6位)
#自动将 tpl = "i am {}, age {}, {}".format("seven", 18, 'zhangsan') print(tpl) #i am seven, age 18, zhangsan tpl = "i am {}, age {}, {}".format(*["seven", 18, 'zhangsan']) print(tpl) #i am seven, age 18, zhangsan tpl = "i am {0}, age {1}, really {0}".format("seven", 18) print(tpl) #i am seven, age 18, really seven tpl = "i am {0}, age {1}, really {0}".format(*["seven", 18]) print(tpl) #i am seven, age 18, really seven tpl = "i am {name}, age {age}, really {name}".format(name="seven", age=18) print(tpl) #i am seven, age 18, really seven tpl = "i am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18}) print(tpl) #i am seven, age 18, really seven tpl = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33]) print(tpl) #i am 1, age 2, really 3 tpl = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1) print(tpl) #i am seven, age 18, money 88888.100000 tpl = "i am {:s}, age {:d}".format(*["seven", 18]) print(tpl) #i am seven, age 18 tpl = "i am {name:s}, age {age:d}".format(name="seven", age=18) print(tpl) #i am seven, age 18 tpl = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18}) print(tpl) #i am seven, age 18 tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2) print(tpl) #numbers: 1111,17,15,f,F, 1587.623000% tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2) print(tpl) #numbers: 1111,17,15,f,F, 1587.623000% tpl = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15) print(tpl) #numbers: 1111,17,15,f,F, 1500.000000% tpl = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15) print(tpl) #numbers: 1111,17,15,f,F, 1500.000000%
#取第几个参数 s1 = '前置 {0} abc {1}'.format('第0个参数','第1个参数') print(s1) #打印结果:前置 第0个参数 abc 第1个参数 #字符串命名 {命名的名字:类型(如果是字符串则是s)} s2 = '---{name:s}_____{age:d}======={name:s}'.format(name = '张三',age = 23) print(s2) #打印结果:---张三_____23=======张三 #fill填充(以1进行填充,但是这里的内容只能是一个字符,不能是12,可以是空格、/n等)、align内容居中、width宽度 s3 = '---{:1^20s}---'.format('哈哈') print(s3) #打印结果:---111111111哈哈111111111--- #sign、#、b s4 = '---{:+d}---{:#b}'.format(123,15) print(s4) #打印结果:---+123---0b1111 #%号(自动转换成百分号的形式,如果没有写保留的数字的话就是默认6位小数位)+保留位数 s5 = 'hahahhh{:.2%}'.format(0.234567) print(s5) #打印结果:hahahhh23.46%
生成器
一、相关释义
1、python2.7里面的range()函数
range(10):一下子就在内存里面生成了10个数,占用内存
xrange(10):生成一个对象(具有生成这些数字的能力),遇到循环的时候才生成,生成0,后面在循环一次的时候生成1(由于垃圾回收机制,会将前面的0给回收掉)
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> xrange(10) xrange(10) >>>
2、python3.5里面的filter()函数,python2里面不支持
3、生成器
3.1、使用函数进行创造
#普通函数 def func(): return 123 ret = func() #生成器 def func(): print('start') yield 1 yield 2 yield 3 ret = func() for i in ret: print(i) #打印结果 ''' start 1 2 3 ''' #没有for循环的时候,执行func()的时候没有执行,只是生成了一个对象 def func(): print('start') yield 1 yield 2 yield 3 ret = func() print(ret) #打印结果:<generator object func at 0x102180888>
3.2、执行特点
#普通函数 def func(): return 123 ret = func() #生成器 def func(): print('start') yield 1 yield 2 yield 3 ret = func() for i in ret: print(i) #打印结果 ''' start 1 2 3 ''' #没有for循环的时候,执行func()的时候没有执行,只是生成了一个对象 def func(): print('111') yield 1 print('222') yield 2 print('333') yield 3 ret = func() r1 = ret.__next__() #进入函数找到yield,获取yield后面的数据,并且退出执行,不执行2 print(r1) r2 = ret.__next__() print(r2) r3 = ret.__next__() print(r3) #打印结果 ''' 111 1 222 2 333 3 ''' #打印结果:<generator object func at 0x102180888>
二、
1、生成器与迭代器
2、相关代码
def myrange(arg): start =0 while True: if start >arg: return yield start start +=1 ret = myrange(10) #不进行循环,也不执行yield r = ret.__next__() #遇到__next__才执行 print(r) #打印结果:0
迭代器
一、相关概念
1、定义
调用__next__的方法进行一个一个迭代
2、特点
2.1、通过__next__的方法进行一个一个迭代
2.2、__next__如果取不到值的话会报错
2.3、for循环的内部,一般就是执行的__next__,所以使用迭代器的话就是利用for循环来实现
函数递归
一、递归相关概念
1、函数无返回值,返回None
2、函数有返回值,返回相对应的返回值
def d(): return '123' def c(): r = d() return r def b(): r = c() return r def a(): r = b() print(r) a() #打印结果:123
3、程序运行相关流程
4、利用for循环进行递归
def func(n): n +=1 if n>=4: return 'end' return func(n) r = func(1) print(r)
5、利用递归实现1*2*3*4*5*6*7
5.1、函数调用其他函数,调用自己,都称之为递归
5.2、相关代码
def func(num): if num == 1: return 1 return num * func(num-1) x = func(7)
模块
一、定义
1、别人提供好的代码:内置模块(下载自带的.py文件)、需要安装的第三方模块、自定义模块
2、内置模块
2.1、sys.args
import sys print(sys.argv) #在终端运行的时候,通过argv输入的是什么参数就通过argv返回什么参数
2.2、使用过程
先导入再使用
2.3、存在方式
.py单个文件
很多个.py文件组成的文件夹
3、第三方模块
4、自定义模块
s2文件
def login(): print('login') def logout(): print('logout')
s1文件
#!/user/bin/env python # -*- coding: utf-8 -*- import s2 s2.logout() #打印结果:logout
二、问答
1、为什么要有模块?
相同的功能写在一个.py文件里面,方便以后调用
将代码归类
2、导入模块的依据?
2.1、当前文件
2.2、内置函数
#导入的模块寻找的依据 import sys for item in sys.path: print(item) #打印结果 ''' /Users/liyueting/sday13:当前执行脚本所在的目录 /Users/liyueting/sday13 :忽略,相关项目的目录 /Library/Frameworks/Python.framework/Versions/3.5/lib/python35.zip /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5 /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/lib-dynload /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages 第三方模块安装的位置 '''
2.3、导入的模块不存在
order模块在E盘,不在相对应的C盘,可通过下面的方式添加即可
import sys sys.path.append('E:\\') import order
3、模块名称的重要性
3.1、如果系统的模块与我们自定义的模块重名,执行的时候,是先执行自定义的文件,顾下面不能运行成功
4、导入模块方式
4.1、import导入
import s2(模块) s2.logout() (函数)
4.2、From导入
from s2(模块) import logout(函数)
from s2 import * #导入所有的函数
4.3、注意点
对于单模块,并且跟程序是在同一个目录下面的时候,为了避免重复,不推荐使用from,直接使用import即可
嵌套在其他文件夹下可以尽量使用from方法
如果两个模块里面的函数出现重复,可将函数定义一个别名来区别
from lib import commons as lib_commons from src import commons as src_commons
三、安装第三方模块
1、requests模块
1.1、通过pip3安装(推荐)
python3自带的pip3 ,python2需要自己安装pip
安装码:pip3 install requests
1.2、通过源码安装
下载源码:https://docs.python.org/3.5/library/urllib.request.html#module-urllib.request
解压源码
执行python3 setup.py install
四、python时间处理之time模块
1、time.time():返回当前系统时间戳
import time print(time.time()) #打印结果:1505274103.872212(目前现在的时间)
1970s:unix系统在这年正式使用
2、time.ctime() :返回当前系统时间(字符串格式)
以秒(second)为单位,可以加减时间并显示成字符串格式的系统时间
import time print(time.ctime()) print(time.ctime(time.time()-86400)) #打印结果 ''' Wed Sep 13 12:08:54 2017 Tue Sep 12 12:08:54 2017 '''
3、time.gmtime();将时间转换成struc_time格式
3.1、tm_wday:星期的计数是从0开始的,一周为0-6 = 7天
3.2、tm_hour = 4 以格林威治时区开始的,从0时区开始;北京:东8区
时区默认展示是从UTC开始的,UTC+8 =北京时间
import time print(time.gmtime()) time_obj = time.gmtime() print(time_obj.tm_year,time_obj.tm_mon) #打印结果 ''' time.struct_time(tm_year=2017, tm_mon=9, tm_mday=13, tm_hour=4, tm_min=11, tm_sec=27, tm_wday=2, tm_yday=256, tm_isdst=0) 2017 9 '''
字符串拼接
import time time_obj = time.gmtime() print("{year}-{month}".format(year = time_obj.tm_year,month = time_obj.tm_mon)) #打印结果 ''' 2017-9 '''
4、time.localtime() :将时间戳转换成struct_time格式,并且返回本地的时间
import time print(time.localtime()) #打印结果 #time.struct_time(tm_year=2017, tm_mon=9, tm_mday=13, tm_hour=12, tm_min=24, tm_sec=59, tm_wday=2, tm_yday=256, tm_isdst=0)
5、time.mktime()
5.1、参数必填,参数为时间对象
5.2、将struc_time格式的时间对象转换成时间戳
import time time_obj = time.gmtime() print(time.mktime(time_obj)) #打印结果:1505248138.0
6、time.sleep():使程序延时X秒钟
6.1、作用:做程序阻塞、循环的应用
6.2、
time.sleep(4) print('____') #打印结果:4秒之后打印____
7、time.strftime(format,p_tuple):将struct_time格式转换成指定的字符串格式
7.1、format:要转换的字符串格式
7.2、p_tuple:时间对象
import time print(time.strftime("%Y-%m_%d %H:%M:%S",time.localtime())) #打印结果:2017-09_13 12:39:01
8、time.strptime():将字符串格式转换成struct_time格式
import time print(time.strptime("2017-09-13 15:06","%Y-%m-%d %H:%M")) #打印结果:time.struct_time(tm_year=2017, tm_mon=9, tm_mday=13, tm_hour=15, tm_min=6, tm_sec=0, tm_wday=2, tm_yday=256, tm_isdst=-1)
9、datetime.date.today() 输出当前的日期,并且是2017-09-13格式
import datetime print(datetime.date.today()) #打印结果:2017-09-13
10、datetime.date.fromtimestamp() 将时间戳转换为日期格式
import datetime import time print(datetime.date.fromtimestamp(time.time()-86400)) #打印结果:2017-09-12
11、datetime.datetime.now() 输出更精确的时间(微毫秒)
import datetime current_time = datetime.datetime.now() print(current_time) #打印结果:2017-09-13 14:19:11.789016
12、将时间格式转换成struct_time格式
import datetime current_time = datetime.datetime.now() print(current_time.timetuple()) #打印结果:time.struct_time(tm_year=2017, tm_mon=9, tm_mday=13, tm_hour=14, tm_min=20, tm_sec=11, tm_wday=2, tm_yday=256, tm_isdst=-1)
13、datetime.timedelta()
13.1、比现在加10天
import datetime current_time = datetime.datetime.now() print(datetime.datetime.now()+datetime.timedelta(days= +10)) #打印结果:2017-09-23 14:24:31.137381
13.2、比现在减10天
import datetime current_time = datetime.datetime.now() print(datetime.datetime.now()+datetime.timedelta(days= -10)) #打印结果:2017-09-03 14:24:51.882485
13.3、比现在减10小时
import datetime current_time = datetime.datetime.now() print(datetime.datetime.now()+datetime.timedelta(hours= -10)) #打印结果:2017-09-13 04:25:44.098551
13.4、比现在加10秒
import datetime current_time = datetime.datetime.now() print(datetime.datetime.now()+datetime.timedelta(seconds= -10)) #打印结果:2017-09-13 14:27:10.867250
17、xxx.replace(年,月,日 时:分:秒)指定日期
import datetime current_time = datetime.datetime.now() print(current_time.replace(2014,9,12)) #打印结果:2014-09-12 14:28:21.048883
18、datetime.datetime.strptime()将字符串转成日期格式
import datetime print(datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")) #打印结果:2006-11-21 16:30:00
19、判断时间的大小
import datetime current_time = datetime.datetime.now() new_time = current_time.replace(2014,9,12) print(current_time == new_time) #打印结果:False
20、不同字符串格式的含义
Directive | Meaning | Notes |
---|---|---|
%a |
Locale’s abbreviated weekday name. | |
%A |
Locale’s full weekday name. | |
%b |
Locale’s abbreviated month name. | |
%B |
Locale’s full month name. | |
%c |
Locale’s appropriate date and time representation. | |
%d |
Day of the month as a decimal number [01,31]. | |
%H |
Hour (24-hour clock) as a decimal number [00,23]. | |
%I |
Hour (12-hour clock) as a decimal number [01,12]. | |
%j |
Day of the year as a decimal number [001,366]. | |
%m |
Month as a decimal number [01,12]. | |
%M |
Minute as a decimal number [00,59]. | |
%p |
Locale’s equivalent of either AM or PM. | (1) |
%S |
Second as a decimal number [00,61]. | (2) |
%U |
Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. | (3) |
%w |
Weekday as a decimal number [0(Sunday),6]. | |
%W |
Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. | (3) |
%x |
Locale’s appropriate date representation. | |
%X |
Locale’s appropriate time representation. | |
%y |
Year without century as a decimal number [00,99]. | |
%Y |
Year with century as a decimal number. | |
%z |
Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59]. | |
%Z |
Time zone name (no characters if no time zone exists). | |
%% |
A literal '%' character. |
五、python日志处理之logging模块
1、单纯的页面打印日志
WARNING:root(超管权限者,日志操作者)+提示内容
import logging logging.warning('user [houza] attempted wrong password more than 3 times') logging.critical('server is down') #打印结果 ''' WARNING:root:user [houza] attempted wrong password more than 3 times CRITICAL:root:server is down '''
2、日志级别
Level | When it’s used |
---|---|
DEBUG(10) |
Detailed information, typically of interest only when diagnosing problems.(最详细的日志信息) |
INFO(20) |
Confirmation that things are working as expected.(仅仅只是记录) |
WARNING(30) |
An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected.(警告) |
ERROR(40) |
Due to a more serious problem, the software has not been able to perform some function.(运行出错) |
CRITICAL(50) |
A serious error, indicating that the program itself may be unable to continue running.(严重错误) |
3、将日志写到文件里面
filename :文件名 level:级别(只有这个级别和比这个级别严重的日志才会写到这个文件里面)
level = logging.INFO :日志级别大于等于INFO的才会记录到这个文件里面,DEBUG级别的日志不进行记录
import logging logging.basicConfig(filename='example.log', level=logging.INFO) logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too') #打印结果 ''' 新建文件example.log并且在这文件里面写入以下内容 INFO:root:So should this WARNING:root:And this, too '''
4、在日志上面加上日期
format
=
'%(asctime)s %(message)s'
, datefmt
=
'%m/%d/%Y %I:%M:%S %p'
format:
asctime:时间的占位符,代表需要写上时间 message:信息,需要在时间占位符的后面
import logging logging.basicConfig(filename='example.log', level=logging.INFO, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this, too') #打印结果 '''
在example.log文件里面写入时间 INFO:root:So should this WARNING:root:And this, too 09/13/2017 08:11:30 PM So should this 09/13/2017 08:11:30 PM And this, too '''
%(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 |
用户输出的消息 |
5、同时将日志打印到屏幕和文件里面
5.1、一些专有名词的解释
loggers:提供了应用程序可以直接使用的接口
handlers:将日志适当的发送到不同的地方
filters:过滤,提供一个方式来过滤日志(例如对于特殊字符的过滤)
formatters:决定日志记录的最终输出格式
5.2、相关代码
当全局的级别是INFO,局部的级别是DEBUG的时候,取的级别是INFO,局部的级别高于等于全局的时候,取的是局部的级别,如果是低的话取的就是全局
import logging # create logger logger = logging.getLogger('TEST-LOG') #命名哪个程序发的日志,当作一个标记,默认是root 获取logger对象,通过命名的logger对象来发送日志 logger.setLevel(logging.DEBUG) #设定一个全局的日志级别 # create console handler and set level to debug 决定输出日志的去处 ch = logging.StreamHandler() #在屏幕上面输出日志 ch.setLevel(logging.DEBUG) #对往屏幕上输出的日志定制级别 # create file handler and set level to warning 往文件里面输出日志 fh = logging.FileHandler("access.log") #往文件里面输出日志 fh.setLevel(logging.WARNING) #对文件上面的日志进行定制日志级别 fh_error = logging.FileHandler("error.log") #往文件里面输出日志 fh_error.setLevel(logging.ERROR) #对文件上面的日志进行定制日志级别 # create formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') formatter_for_file = logging.Formatter('%(asctime)s-%(filename)s-%(levelname)s - %(message)s') # add formatter to ch and fh ch.setFormatter(formatter) #对屏幕设定输出格式 fh.setFormatter(formatter_for_file) #对文件设定输出格式 fh_error.setFormatter(formatter) #对屏幕设定输出格式 # add ch and fh to logger logger.addHandler(ch) #将输出的日志告诉logger,打印到指定的位置--屏幕 logger.addHandler(fh) #将输出的日志告诉logger,打印到指定的位置--文件 logger.addHandler(fh_error) #将输出的日志告诉logger,打印到指定的位置--屏幕 # 'application' code logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message')
屏幕输出
2017-09-13 20:33:13,073 - TEST-LOG - DEBUG - debug message 2017-09-13 20:33:13,074 - TEST-LOG - INFO - info message 2017-09-13 20:33:13,074 - TEST-LOG - WARNING - warn message 2017-09-13 20:33:13,074 - TEST-LOG - ERROR - error message 2017-09-13 20:33:13,074 - TEST-LOG - CRITICAL - critical message 时间+指定的操作人+格式+日志级别+消息
access文件输出
2017-09-13 20:33:13,074 - WARNING - warn message 2017-09-13 20:33:13,074 - ERROR - error message 2017-09-13 20:33:13,074 - CRITICAL - critical message 2017-09-13 20:41:41,904 - WARNING - warn message 2017-09-13 20:41:41,905 - ERROR - error message 2017-09-13 20:41:41,905 - CRITICAL - critical message 2017-09-13 20:45:30,060 - test.py-WARNING - warn message 2017-09-13 20:45:30,060 - test.py-ERROR - error message 2017-09-13 20:45:30,061 - test.py-CRITICAL - critical message 2017-09-13 20:45:55,188-test.py-WARNING - warn message 2017-09-13 20:45:55,189-test.py-ERROR - error message 2017-09-13 20:45:55,189-test.py-CRITICAL - critical message 2017-09-13 20:50:16,592-test.py-WARNING - warn message 2017-09-13 20:50:16,593-test.py-ERROR - error message 2017-09-13 20:50:16,593-test.py-CRITICAL - critical message
error文件输出
2017-09-13 20:41:41,905 - TEST-LOG - ERROR - error message 2017-09-13 20:41:41,905 - TEST-LOG - CRITICAL - critical message 2017-09-13 20:45:30,060 - TEST-LOG - ERROR - error message 2017-09-13 20:45:30,061 - TEST-LOG - CRITICAL - critical message 2017-09-13 20:45:55,189 - TEST-LOG - ERROR - error message 2017-09-13 20:45:55,189 - TEST-LOG - CRITICAL - critical message 2017-09-13 20:50:16,593 - TEST-LOG - ERROR - error message 2017-09-13 20:50:16,593 - TEST-LOG - CRITICAL - critical message
6、日志格式
%(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 |
用户输出的消息 |
python序列化模块(也是属于模块)
一、python序列化之json
1、定义
将列表、创建的对象、字典这些python的数据类型转换成字符串
作用:进行跨语言之间的交互
2、json.dumps
通过json.dumps就可以将python的基础数据类型转换成字符串形式,如下代码
import json dit = {'k1':'V1'} print(dit,type(dit)) result = json.dumps(dit) print(result,type(result)) #打印结果 ''' {'k1': 'V1'} <class 'dict'> {"k1": "V1"} <class 'str'> #字典形态的字符串 '''
3、json.loads
将python字符串形式转换成基本的数据类型
单引号引起的是字符,双引号里面引起的是字符串,所以在跨语言之间只能用双引号才可以
import json s1 = '{"k1":"v1"}' #单引号引起的是字符,双引号里面引起的是字符串,所以在跨语言之间只能用双引号才可以 dic = json.loads(s1) print(dic,type(dic)) #打印结果 ''' {'k1': 'v1'} <class 'dict'> '''
4、基于天气API获取天气相关JSON数据
request库里面获取到数据之后通过XXX.text来存储
import requests import json response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=北京') #打开链接 response.encoding = 'utf-8' #通过‘utf-8’编码打开
print(response.text,type(response.text)) dic = json.loads(response.text) print(dic,type(dic))
5、json.dump
先将其进行序列化,并且将内容写到文件里面
import json li = [11,22,33] json.dump(li,open('s1','w')) #先将其进行序列化,并且将内容写到文件里面
6、json.load
打开文件,并且将文件反序列化读取出来
import json li =json.load(open('s1','r')) #打开文件,并且将文件反序列化读取出来 print(type(li),li) #打印结果:<class 'list'> [11, 22, 33]
二、python序列化之pickle
1、与json的区别
pickle只适用于python,不能跨语言
2、用法
2.1、dumps()
import pickle li = [11,22,33,44] r = pickle.dumps(li) print(r) #打印结果:b'\x80\x03]q\x00(K\x0bK\x16K!K,e.'
2.2、loads()
import pickle li = [11,22,33,44] r = pickle.dumps(li) r1 = pickle.loads(r) print(r1) #打印结果:[11, 22, 33, 44]
2.3、dump()
只支持字节的方式写入,不然会报错:TypeError: write() argument must be str, not bytes
import pickle li = [11,22,33,44] r2 = pickle.dump(li,open('test','wb')) print(r2) #打印结果:None
2.4、load()
只支持字节的方式读取,不然会报错:TypeError: write() argument must be str, not bytes
import pickle li = [11,22,33,44] r3 = pickle.load(open('test' ,'rb')) print(r3) #打印结果:[11, 22, 33, 44]
3、使用方法区别(json与pickle)
json:只支持 列表、字典、元组等基本的数据类型
跨语言(基本都是通过字符串交流的)
pickle:支持任何类型(自己写的类什么的)
只适用于python语言的复杂类型做操作
python之间的版本不同,可能会有相对应的兼容问题