python 继承引用导致对象无法释放

1,scp传输数据失败

  • 涉及知识
    • ssh key设置
    • A访问B机器,需要将A的公钥加到B机器的

2,文件数打开过多

  • 找到进程Id
  • 对于此进程进行lsof -p PID | wc -l 查看打开了多少文件
  • ulimit -a 查看本机限制打开多少文件

3,跟进为啥文件数打开过多

  • 初步判定是因为自定义了 exit 魔法方法,导致继承父类的self.logger没有被释放
  • 然后每次请求会新生成一个对象,对象又无法释放

代码如下

#!/usr/bin/env python2
# -*- coding:utf-8 -*-

__all__ = ['Timer', 'Script']

import os
import time
import logging
from datetime import datetime


# from flask import current_app


class Timer(object):
    """
    简易定时器,通过with上下文语句自动输出或打印运行时间日志
    """

    def __init__(self, title: str, show: bool = True, logger: logging.Logger = None) -> None:
        """
        :param title: 定时器的标题
        :param show: 是否在shell打印
        :param logger: 日志对象
        """
        self.title = title
        self.show = show
        self.logger = logger

    def __enter__(self) -> 'Timer':
        self.start = time.clock()
        if self.show:
            print(f'{self.title} start\n')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        end = time.clock()
        message = f'{self.title} waiting {str((end - self.start) * 1000)} microseconds'
        if self.show:
            print(f'{self.title} stop\n')
            print(message)
        if self.logger:
            self.logger.info(message)
        print(logging.FileHandler) # 这里可以看到每次都引用了父类的元素


class Script(object):
    """
    脚本对象,包含计时工具/日志工具/数据库处理工具/邮件工具
    """

    def __init__(
            self,
            level: int = logging.INFO,
            log_format: str = '[%(levelname)s] %(asctime)s %(pathname)s[line:%(lineno)d] %(message)s',
            log_file_format: str = '%Y-%m-%d-%H-%M-%S.log'
    ) -> None:
        name = self.__class__.__name__
        self.logger = logging.getLogger(name)
        self.logger.setLevel(level)
        # log_dir = current_app.config['LOG_DIR']
        log_dir = "./"
        dir_name = os.path.join(log_dir, name)
        if not os.path.exists(log_dir):
            os.mkdir(log_dir)
        if not os.path.exists(dir_name):
            os.mkdir(dir_name)
        file_handler = logging.FileHandler(
            os.path.join(
                dir_name,
                datetime.now().strftime(log_file_format)
            )
        )
        file_handler.setLevel(level)
        file_handler.setFormatter(logging.Formatter(log_format))
        self.logger.addHandler(file_handler)
        print(id(self.logger))

    def timer(self, title: str = None, show: bool = True) -> Timer:
        """
        返回计时器实例,通过with语句可自动打印代码块的运行耗时情况
        :param title: 定时器的标题
        :param show: 是否在shell打印
        """
        return Timer(
            title=title or self.__class__.__name__,
            show=show, logger=self.logger
        )

    def log_num_check(self):
        print(datetime.now())


if __name__ == '__main__':
    while True:
        script = Script(log_file_format='%Y-%m-%d.log')
    
        with script.timer():
            script.log_num_check()
        time.sleep(0.5)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值