双层装饰器、字符串格式化、生成器、模块

双层装饰器

#!/usr/bin/env python
#-*- coding:utf-8 -*-
USER_INFO = {}
USER_INFO['is_login'] = False
USER_INFO['user_type'] = 2
def check_login(func):
    def inner(*args, **kwargs):
        if USER_INFO.get('is_login',None):
            ret = func(*args, **kwargs)
            return ret
        else:
            print('请登录')
    return inner
def check_admin(func):
    def inner(*args, **kwargs):
        if USER_INFO.get('user_type',None) == 2:
            ret = func(*args, **kwargs)
            return ret
        else:
            print('无权限查看')
    return inner
@check_login
@check_admin
def index():
    print('index')
index()

字符串格式化

Python的字符串格式化有两种方式: 百分号方式、format方式

百分号的方式相对来说比较老,而format方式则是比较先进的方式,目前两者并存。


1、百分号方式
    %[(name)][flags][width].[precision]typecode

    (name)      可选,用于选择指定的key
    flags          可选,可供选择的值有:
        +       右对齐;正数前加正好,负数前加负号;
        -        左对齐;正数前无符号,负数前加负号;
        空格    右对齐;正数前加空格,负数前加负号;
        0        右对齐;正数前无符号,负数前加负号;用0填充空白处
    width         可选,占有宽度
    .precision   可选,小数点后保留的位数
    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;)
        %,当字符串中存在格式化标志时,需要用 %%表示一个百分号

注:Python中百分号格式化是不存在自动将整数转换成二进制表示的方式

常用格式化:

tpl = "i am %s" % "wangxin"
 
tpl = "i am %s age %d" % ("wangxin", 18)
 
tpl = "i am %(name)s age %(age)d" % {"name": "wangxin", "age": 18}
 
tpl = "percent %.2f" % 99.97623
 
tpl = "i am %(pp).2f" % {"pp": 123.425556, }
 
tpl = "i am %.2f %%" % {"pp": 123.425556, }


2、Format方式

    [[fill]align][sign][#][0][width][,][.precision][type]

    fill           【可选】空白处填充的字符
    align        【可选】对齐方式(需配合width使用)
        <,内容左对齐
        >,内容右对齐(默认)
        =,内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
        ^,内容居中
    sign         【可选】有无符号数字
        +,正号加正,负号加负;
         -,正号不变,负号加负;
        空格 ,正号空格,负号加负;
    #            【可选】对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显示
    ,            【可选】为数字添加分隔符,如:1,000,000
    width       【可选】格式化位所占宽度
    .precision 【可选】小数位保留精度
    type         【可选】格式化类型
        传入” 字符串类型 “的参数
            s,格式化字符串类型数据
            空白,未指定类型,则默认是None,同s
        传入“ 整数类型 ”的参数
            b,将10进制整数自动转换成2进制表示然后格式化
            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, 'alex')
  
tpl = "i am {}, age {}, {}".format(*["seven", 18, 'alex'])
  
tpl = "i am {0}, age {1}, really {0}".format("seven", 18)
  
tpl = "i am {0}, age {1}, really {0}".format(*["seven", 18])
  
tpl = "i am {name}, age {age}, really {name}".format(name="seven", age=18)
  
tpl = "i am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18})
  
tpl = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])
  
tpl = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1)
  
tpl = "i am {:s}, age {:d}".format(*["seven", 18])
  
tpl = "i am {name:s}, age {age:d}".format(name="seven", age=18)
  
tpl = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})
 
tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
 
tpl = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)



迭代器和生成器

1、迭代器
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件
特点:
   1 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
   2 不能随机访问集合中的某个值 ,只能从头到尾依次访问
   3 访问到一半时不能往回退
   4 便于循环比较大的数据集合,节省内存

>>> a = iter([1,2,3,4,5])
>>> a
<list_iterator object at 0x101402630>
>>> a.__next__()
1
>>> a.__next__()
2
>>> a.__next__()
3
>>> a.__next__()
4
>>> a.__next__()
5
>>> a.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration


def myrange(arg):
   start = 0
    while True:
        if start > arg:
            return
        yield start
        start += 1
ret = myrange(2)
# r = ret.__next__()
# print(r)
# r = ret.__next__()
# print(r)
# r = ret.__next__()
for item in ret:
    print(item)

2、生成器

一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);如果函数中包含yield语法,那这个函数就会变成生成器;

def func():
    yield 1
    yield 2
    yield 3
    yield 4


上述代码中:func是函数称为生成器,当执行此函数func()时会得到一个迭代器。

>>> temp = func()
>>> temp.__next__()
1
>>> temp.__next__()
2
>>> temp.__next__()
3
>>> temp.__next__()
4
>>> temp.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

模块

模块,用一砣代码实现了某个功能的代码集合。 

类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。

如:os 是系统相关的模块;file是文件操作相关的模块

模块分为三种:

  • 自定义模块

  • 第三方模块

  • 内置模块


导入模块
如果想要使用模块,则需要导入。导入模块有一下几种方法:
    
import module
from module.xx.xx import xx
from module.xx.xx import xx as rename
from module.xx.xx import *

导入模块其实就是告诉Python解释器去解释那个py文件
    导入一个py文件,解释器解释该py文件
    导入一个包,解释器解释该包下的 __init__.py 文件

导入模块时根据的路径,即:sys.path    
import sys
print sys.path
   
结果:
['C:\\Users\\kingroll\\PycharmProjects\\s13\\day5', 'C:\\Users\\kingroll\\PycharmProjects\\s13', 'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib', 'C:\\Python36', 'C:\\Python36\\lib\\site-packages']

如果sys.path路径列表没有你想要的路径,可以通过 sys.path.append('路径') 添加。

import sys
import os
project_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(project_path)

第三方模块
安装requests模块
pip3安装
 pip3 install requests

源码安装
 进入解压目录
 python3 setup.py install



内置模块

内置模块是Python自带的功能,在使用内置模块相应的功能时,需要【先导入】再【使用】

一、sys

用于提供对Python解释器相关的操作:    
sys.argv           命令行参数List,第一个元素是程序本身路径
sys.exit(n)        退出程序,正常退出时exit(0)
sys.version        获取Python解释程序的版本信息
sys.maxint         最大的Int值
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       返回操作系统平台名称
sys.stdin          输入相关
sys.stdout         输出相关
sys.stderror       错误相关
进度百分比

import sys
import time
def view_bar(num, total):
    rate = float(num) / float(total)
    rate_num = int(rate * 100)
    r = '\r%d%%' % (rate_num, )
    sys.stdout.write(r)
    sys.stdout.flush()
if __name__ == '__main__':
    for i in range(0, 100):
        time.sleep(0.1)
        view_bar(i, 100)

二、os

用于提供系统级别的操作:    
os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")         改变当前脚本工作目录;相当于shell下cd
os.curdir                   返回当前目录: ('.')
os.pardir                   获取当前目录的父目录字符串名:('..')
os.makedirs('dir1/dir2')    可生成多层递归目录
os.removedirs('dirname1')   若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')         生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')         删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')       列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()                 删除一个文件
os.rename("oldname","new")  重命名文件/目录
os.stat('path/filename')    获取文件/目录信息
os.sep                      操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep                  当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep                  用于分割文件路径的字符串
os.name                     字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")   运行shell命令,直接显示
os.environ                  获取系统环境变量
os.path.abspath(path)       返回path规范化的绝对路径
os.path.split(path)         将path分割成目录和文件名二元组返回
os.path.dirname(path)       返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)      返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)        如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)         如果path是绝对路径,返回True
os.path.isfile(path)        如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)         如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)      返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)      返回path所指向的文件或者目录的最后修改时间


三、序列化

Python中用于序列化的两个模块

  • json     用于【字符串】和 【python基本数据类型】 间进行转换

  • pickle   用于【python特有的类型】 和 【python基本数据类型】间进行转换

Json模块提供了四个功能:dumps、dump、loads、load

pickle模块提供了四个功能:dumps、dump、loads、load


import json

dic = {'k1':'v1'}
print(dic,type(dic))

#将python基本数据类型转化成字符串形式
result = json.dumps(dic)
print(result,type(result))

s1 = '{"k1":123}'
#将python字符串形式转化成基本数据类型
dic1 = json.loads(s1)
print(dic1,type(dic1))

import json
r = json.dumps([11,22,33])
li = '["wangxin","yuehan"]'
#li = "['wangxin','yuehan']"
ret = json.loads(li) #反序列化时,一定要使用""  跨语言之间的统一
print(ret,type(ret))
import json
li = [11,22,33]
#先进行序列化,然后写进文件
json.dump(li,open('db','w'))
#先读文件,再转化,
li =json.load(open('db','r'))
print(type(li),li)

pickle只能python用.用法与json大致相同
json只能处理基本数据类型,pickle支持任何类型
json更加适合跨语言,字符串,基本数据类型;pickle,python复杂类型的序列化操作

import pickle
li = [11,22,33]
r = pickle.dumps(li)
print(r)
result = pickle.loads(r)
print(result)


li = [11,22,33]
pickle.dump(li,open('db1','wb'))
result = pickle.load(open('db1','rb'))
print(result,type(result))

四、time

时间相关的操作,时间有三种表示方式:

    时间戳               1970年1月1日之后的秒,即:time.time()
    格式化的字符串    2014-11-11 11:11,    即:time.strftime('%Y-%m-%d')
    结构化时间          元组包含了:年、日、星期等... time.struct_time    即:time.localtime()

import time

# print(time.asctime()) #返回时间格式"Fri Aug 19 11:14:16 2016",
# print(time.localtime()) #返回本地时间 的struct time对象格式
# print(time.gmtime(time.time()-800000)) #返回utc时间的struc时间对象格式

# print(time.asctime(time.localtime())) #返回时间格式"Fri Aug 19 11:14:16 2016",
#print(time.ctime()) #返回Fri Aug 19 12:38:29 2016 格式, 同上

# 日期字符串 转成  时间戳
# string_2_struct = time.strptime("2016/05/22","%Y/%m/%d") #将 日期字符串 转成 struct时间对象格式
# print(string_2_struct)
# #
# struct_2_stamp = time.mktime(string_2_struct) #将struct时间对象转成时间戳
# print(struct_2_stamp)

#将时间戳转为字符串格式
# print(time.gmtime(time.time()-86640)) #将utc时间戳转换成struct_time格式
# print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将utc struct_time格式转成指定的字符串格式

#时间加减
import datetime

'''
datetime.date:表示日期的类。常用的属性有year, month, day
datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond
datetime.datetime:表示日期时间
datetime.timedelta:表示时间间隔,即两个时间点之间的长度
timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])
strftime("%Y-%m-%d")
'''

# print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925
#print(datetime.date.fromtimestamp(time.time()) )  # 时间戳直接转成日期格式 2016-08-19
# print(datetime.datetime.now() )
# print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
# print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
# print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
# print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分

# c_time  = datetime.datetime.now()
# print(c_time.replace(minute=3,hour=2)) #时间替换
%Y  Year with century as a decimal number.
    %m  Month as a decimal number [01,12].
    %d  Day of the month as a decimal number [01,31].
    %H  Hour (24-hour clock) as a decimal number [00,23].
    %M  Minute as a decimal number [00,59].
    %S  Second as a decimal number [00,61].
    %z  Time zone offset from UTC.
    %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.
    %I  Hour (12-hour clock) as a decimal number [01,12].
    %p  Locale's equivalent of either AM or PM.
格式化占位符

五、logging模块

最简单的用法

import logging
 
logging.warning("user [wangxin] attempted wrong password more than 3 times")
logging.critical("server is down")
 
#输出
WARNING:root:user [wangxin] attempted wrong password more than 3 times
CRITICAL:root:server is down

日志等级:

     Level                                               When it’s used
   DEBUG          Detailed information, typically of interest only when diagnosing problems.
   INFO             Confirmation that things are working as expected.
 WARNING      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           Due to a more serious problem, the software has not been able to perform some function.
  CRITICAL       A serious error, indicating that the program itself may be unable to continue running.

把日志写到文件里

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')

其中下面这句中的level=logging.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。

logging.basicConfig(filename='example.log',level=logging.INFO)

上面的日志格式忘记加上时间,日志不知道时间怎么行呢,加上时间

import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')
 
#输出
12/12/2010 11:46:36 AM is when this event was logged.

注:只有【当前写等级】大于【日志等级】时,日志文件才被记录。

日志记录格式:

%(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

用户输出的消息


如果想同时把log打印在屏幕和文件日志里,就需要了解一点复杂的知识 了


Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:

logger提供了应用程序可以直接使用的接口;

handler将(logger创建的)日志记录发送到合适的目的输出;

filter提供了细度设备来决定输出哪条日志记录;

formatter决定日志记录的最终输出格式。

logger
每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
LOG=logging.getLogger(”chat.gui”)
而核心模块可以这样:
LOG=logging.getLogger(”chat.kernel”)

Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

 

handler

handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象


每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:
1)    logging.StreamHandler
使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:
StreamHandler([strm])
其中strm参数是一个文件对象。默认是sys.stderr


2)   logging.FileHandler
和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:
FileHandler(filename[,mode])
filename是文件名,必须指定一个文件名。
mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。

3)   logging.handlers.RotatingFileHandler
这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中filename和mode两个参数和FileHandler一样。
maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。


4)   logging.handlers.TimedRotatingFileHandler
这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
S 秒
M 分
H 小时
D 天
W 每星期(interval==0时代表星期一)
midnight 每天凌晨

import logging
 
#create logger
logger = logging.getLogger('TEST-LOG')
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)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
 
# add formatter to ch and fh
ch.setFormatter(formatter)
fh.setFormatter(formatter)
 
# add ch and fh to logger
logger.addHandler(ch)
logger.addHandler(fh)
 
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

文件自动截断

import logging
from logging import handlers
logger = logging.getLogger(__name__)
log_file = "timelog.log"
#fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)
fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3)
formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.warning("test1")
logger.warning("test12")
logger.warning("test13")
logger.warning("test14")


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章