日志的轮转 按时间 日志文件名称接的是开始时间 TimedRotatingFileHandler 按大小 一般日志文件名称接的是大小 RotatingFileHandler #按照大小轮转创建 #传入参数:名字 最大字节 备份数量 fh=RotatingFileHandler("sc-bak.log",maxBytes=100,backupCount=2) #按时间轮转创建处理器 #传入参数:名字 时间单位 周期(这里表示2s轮转一次) 备份数量(保留几个历史轮转文件 2个) fh=TimedRotatingFileHandler("sc.log",when="S",interval=2,backupCount=2) Linux里面/etc/logrotate里rorate=4表示保留4个历史日志文件 搭建一个程序考虑的方面:日志 监控 #按时间轮转创建处理器 import logging import time from logging.handlers import TimedRotatingFileHandler,RotatingFileHandler logger=logging.getLogger() #按时间轮转创建处理器 #传入参数:名字 时间单位 周期(这里表示2s轮转一次) 备份数量(保留几个历史轮转文件 2个) fh=TimedRotatingFileHandler("sc.log",when="S",interval=2,backupCount=2) #按照大小轮转创建 #传入参数:名字 最大字节 备份数量 fh=RotatingFileHandler("sc-bak.log",maxBytes=100,backupCount=2) logger.addHandler(fh) ch=logging.StreamHandler() logger.addHandler(ch) formatter=logging.Formatter("%(asctime)s - %(filename)s - %(levelname)s:%(message)s") fh.setFormatter(formatter) for i in range(200): #time.sleep(0.5) logger.warning("this is warining...") 装饰器添加额外功能: 计时 权限控制 日志记录 可以在一个函数上面引用两个装饰器 装饰器带参数: 自身不传入参数的装饰器,使用两层函数定义 自身传入函数的装饰器,使用三层函数定义 import time def deco(username): def runtime(func): def inner(*args,**kwargs): print(f"装饰器带参数:{username}") start=time.time() result=func(*args,**kwargs) end=time.time() print(f"{func.__name__}执行花了{end-start}s") return result return inner return runtime # @deco #add=deco(add)运行的是runtime @deco(username="sc") #runtime=deco(username="sc") add=runtime(add) @deco("sc") #这两行效果一样 def add(a,b): return a+b add(1,2) #输出结果: # 装饰器带参数:sc # add执行花了0.0s 属性包装装饰器:常常用在设置属性的时候对属性的判断 property 把方法当作属性来使用 class Person(): _age=1 @property #property本身会创建另外两个装饰器 # @age.setter @age.deleter(被装饰的话名字叫什么 装饰器就叫什么) def age(self):#把这个age当作属性使用 如果给它赋值则会自动调用age.setter return self._age @age.setter def age(self,num): #这个函数最好与上面重名 if 0<num<140: self._age=num else: raise ValueError("年龄不在范围") p=Person() print(p.age) p.age=110 print(p.age) #输出结果:1 # 110 #用类去实现装饰器 class A(): def __init__(self,func): self.func=func def __call__(self,*args,**kwargs): print("this is call") result=self.func(*args,**kwargs) return result @A #func1=A(func1) def func1(): print("i am func1") func1() 输出结果: this is call i am func1 带参数的装饰器用类实现 class A(): def __init__(self, name): self.name = name def __call__(self, func): def inner(*args,**kwargs): print(self.name) func(*args,**kwargs) return inner #若是不定义新函数 返回原函数 # 那函数不执行时装饰器就已经执行了原函数 @A("sc123") #a=A("sc")实例化传的参数 # func1=a(func1) 运行的__call__方法 def func123(): print("i am func1") func123() 装饰器装饰类: def outer(cls): def inner(*args,**kwargs): print(f"class name is {cls.__name__}") return cls(*args,**kwargs) return inner @outer #A=outer(A) class A: def __init__(self,name): self.name=name a1=A('sc')#输出class name is A