python闭包、日志模块与装饰器

闭包

定义

什么是闭包

• 在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生 闭包。
•闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。
• 在给定函数被多次调用的过程中,这些私有变量能够保持其持久性

闭包的概念很简单:一个可以引用在函数闭合范围内变量的函数。即"内部函数",只有那个内部函 数才有所谓的__closure__属性。

闭包的好处

闭包的好处

• 闭包不是必须的。
• 没了闭包,python的功能一点不会被影响
• 有了闭包,只是提供给你一种额外的解决方案

装饰器

什么是装饰器

装饰器其实就是闭包

装饰器是这样一种设计模式:如果一个类(函数)希望添加其他类(函数)的一些功能,而不希望通过继承或是直接修改源代码实现,那么可以使用装饰器模式。

•简单来说Python中的装饰器就是指某些函数或其他可调用对象,以函数或类作为可选输入参数,然后返回函数或类的形式。通过这个在Python2.6版本中被新加入的特性可以用来实现装饰器设计 模式。

• 装饰器就是一个可以接受调用也可以返回调用的函数,该函数接受被装饰的函数作为其位置参数。装饰器通过使用该参数来执行某些操作,然后返回原始参数或一些其他的调用

函数也是对象,也可以当做参数传递

装饰器有什么用

• 你可以考虑在装饰器中置入通用功能的代码来降低程序复杂度。例如,可以用装饰器来:
• 引入日志
• 增加计时逻辑来检测性能
• 给函数加入事务的能力
• 权限控制

应用多个装饰器
•装饰器函数在被装饰函数定义好后立即执行从下往上执行
函数调用时从上到下执行
如:

import logging
logger=logging.getLogger()
fh=logging.FileHandler("sc.log",encoding='utf-8')
ch=logging.StreamHandler()
foematter=logging.Formatter("%(asctime)s-%(levelname)s:%(message)s")
fh.setFormatter(foematter)
ch.setFormatter(foematter)
logger.addHandler(fh)
logger.addHandler(ch)
logger.setLevel(logging.DEBUG)

def Name(func):
    print("i am name1")
    def inner(*args,**kwargs):
        print("i am name2")
        re=func(*args,**kwargs)
        logger.warning(f"执行了{func.__name__}函数")
        return re
    return inner

import time
def Time(func):
    print("i am time1")
    def inner(*args,**kwargs):
        print("i am time2")
        start=time.time()
        re=func(*args,**kwargs)
        end=time.time()
        print(f"共花费了{end-start}")
        return re
    return inner

@Time
@Name
def func(a):
    time.sleep(2)
    return a

print(func("af"))

从下到上依次执行,结果:

i am name1
i am time1
i am time2
i am name2
共花费了2.010303020477295
af
2021-08-02 15:16:11,351-WARNING:执行了func函数

日志

日志是一种可以追踪某些软件运行时所发生事件的方法

通过日志可以做什么事情?

1、排错
    分析和定位故障
2、程序调试
    了解程序的运行情况,是否正常
3、用户行为分析

python logging 模块

五个日志级别:(处理事情要分一个轻重缓急)
日志等级 数值表示 描述

DEBUG         10       最详细的日志信息,常用于调试
INFO          20       详细日志信息仅次于DEBUG,记录关键节点的信息
WARNING       30(默认等级) 当前有不期望的事情发生
ERROR         40        发生错误问题导致某些功能不能正常使用
CRITICAL      50        发生了严重错误导致程序不能运行了

logging 日志系统的四大组件

#日志器  Logger
#处理器  Handler
#过滤器  Filter
#格式器  Formatter
# import logging
# LOG_FORMAT = "%(asctime)s-%(levelname)s:%(message)s"
# DATE_FORMAT = "%m/%d/%Y %H:%M:%S"
# logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT,
#                     datefmt=DATE_FORMAT, filename="my.log")
# logging.debug("this is debug message")
# logging.info("this is info message")
# logging.warning("this is warning message")
# logging.error("this is error message")


import logging
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler

#获取logger对象,用于记录日志
logger = logging.getLogger()

#handler对象,用于写入日志,规定日志输出到哪里
#写入文件
#fh = logging.FileHandler("my.log")
#日志轮转
fh = RotatingFileHandler("my.log", maxBytes=500, backupCount=2)
#按照两天时间轮转一次,保留三个备份
# fh = TimedRotatingFileHandler("my.log", when="D", interval=2, backupCount=3)
#输出到屏幕
ch = logging.StreamHandler()

#创建formatter,用于处理日志格式
formatter = logging.Formatter("%(asctime)s-%(levelname)s:%(message)s")

#绑定formatter到hander上
fh.setFormatter(formatter)

#绑定handler到logger对象上
logger.addHandler(fh)
logger.addHandler(ch)

#设置日志等级
logger.setLevel(logging.DEBUG)
for i in range(1000):
   logger.warning("this is warning....")

#生成logger对象的时候,没有传递参数进去,那生成的就是root logger  类似 /
#传递name进去之后 类似 /sc
#子日志器会继承父日志器的配置
# logger2 = logging.getLogger("sc")
# logger2.warning("this is sc2 logger")
#
# #类似/sc/xx
# logger3 = logging.getLogger("sc.xx")
# logger3.warning("test test test")

例子

#作业编写日志记录装饰器
#比如执行了func1函数,那就日志记录“执行了func1函数,花费多久时间” ,日志的格式要包含时间
#日志要输出到文件(xu.log)和屏幕
import logging
import time
#获取logger对象,用于记录日志
logger = logging.getLogger()
logger.setLevel(logging.INFO)
#handler对象,用于写入日志,规定日志输出到哪里
#输出到文件
fh = logging.FileHandler("xu.log")
#输出到屏幕
ch = logging.StreamHandler()
#时间格式
format=logging.Formatter("%(asctime)s,%(message)s")
fh.setFormatter(format)
ch.setFormatter(format)
# 绑定handler
logger.addHandler(fh)
logger.addHandler(ch)
def defpro(func):
    def inner():
        start=time.time()
        func()
        end=time.time()

        logger.info("执行了%s函数,花费%s"%(func.__name__,end-start))
    return inner

@defpro
def fun1():
    time.sleep(2)
@defpro
def fun2():
    time.sleep(1)

fun2()
fun1()
fun2()

执行结果为:

2021-08-02 14:56:12,495,执行了fun1函数,花费2.0094385147094727
2021-08-02 14:56:13,498,执行了fun2函数,花费1.0029654502868652
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值