魔术方法
在类方法中__init__ 方法有什么作用?
创建对象时,自动调用对创建的对象进行初始化设置。
什么是魔术方法?
在python中,像 __init__这类双下滑线开头和结尾的方法,统一称之为魔术方法。
注意:在我们自己封装方法时,千万不要用双下划线开头或者结尾的方法定义,魔术方法时python内部自己定义的方法。
创建单例模式
我们在创建类的时候,每次调用时,都会实例化一个对象,那么如果我们要求这个类只会被实例化一次,应该怎么做呢?
class Demo(object):
__instance = None
def __new__(cls, *args, **kwargs):
if cls.__instance is None:
instance = super().__new__(cls)
cls.__instance = instance
return cls.__instance
deom1 = Demo()
deom2 = Demo()
print(id(deom1), id(deom2))
结果:
1401905908320 1401905908320
通过返回结果,我们看到他们调用的是同一个内存地址
单例模式在工作中的使用场景,假设我们类在工作中需要创建非常多的对象,不同的对象他们调用的内部方法都是相同的,比如日志模块。通常我们定义的日志模块,在不同的地方调用日志,都需要调用一个对象。在python中,如果我们通过类去创建对象,那么就是一个日志收集器。如果说我们创建多个的话,就会导致日志重复收集。
import os
import logging
from logging.handlers import TimedRotatingFileHandler, BaseRotatingHandler
import colorama
colorama.init()
class Logger:
__instance = None
sh = logging.StreamHandler()
def __new__(cls, path=None, level='DEBUG'):
"""
:param path: report path
:param args:
:param kwargs:
:return:
"""
if not cls.__instance:
cls.__instance = super().__new__(cls)
log = logging.getLogger('apin-ui')
log.setLevel(level)
cls.__instance.log = log
return cls.__instance
def set_level(self, level):
"""设置日志输出的等级"""
self.log.setLevel(level)
def set_file_handle(self, level, path):
if path:
if not os.path.isdir(path):
os.mkdir(path)
fh = TimedRotatingFileHandler(os.path.join(path, 'apin-ui.log'), when='d',
interval=1, backupCount=7,
encoding="utf-8")
fh.setLevel(level)
self.log.addHandler(fh)
formatter = logging.Formatter("%(asctime)s | 【%(levelname)s】 | : %(message)s")
fh.setFormatter(formatter)
def debug(self, message):
self.fontColor('\033[0;34m{}\033[0;34m{}\033[0;34m{}')
self.log.debug(message)
def info(self, message):
self.fontColor('\033[0;32m{}\033[0;32m{}\033[0;32m{}')
self.log.info(message)
def warning(self, message):
self.fontColor('\033[0;33m{}\033[0;43m{}\033[0;33m{}')
self.log.warning(message)
def error(self, message):
self.fontColor('\033[0;31m{}\033[0;41m{}\033[0;31m{}')
self.log.error(message)
def exception(self, message):
self.fontColor('\033[0;31m{}\033[0;41m{}\033[0;31m{}')
self.log.exception(message)
def critical(self, message):
self.fontColor('\033[0;35m{}\033[0;45m{}\033[0;35m{}')
self.log.critical(message)
def fontColor(self, color):
formatter = logging.Formatter(color.format("%(asctime)s| ", "【%(levelname)s】", " | : %(message)s"))
self.sh.setFormatter(formatter)
self.log.addHandler(self.sh)
def print_info(msg):
print('\033[0;32m{}'.format(msg))
def print_waring(msg):
print('\033[0;33m{}'.format(msg))
def print_error(msg):
print('\033[0;31m{}'.format(msg))
if __name__ == '__main__':
logger = Logger()
logger.debug('debu等级日志')
logger.info('info日志')
logger.warning('warning日志')
logger.error('error日志')
logger.critical('CRITICAL日志')
上下文管理器
在我们使用python中的with open方法去打开文件,有没有思考过,为什么with open方法打开文件,会自动关闭?
这里我们就需要了解到上下文管理器的概念:
上下文管理器是一个python对象,为操作提供了额外的上下文信息。这种额外信息,在使用 with 语句初始化上下文,以及完成 with 代码块中采用所有可调用的形式。
- object.enter(self)
输入与次对象相关的上下文。如果存在的话,with 语句将绑定该方法的返回值到该一句的as子句子指定的目标。 - object.exit(self, exc_type, exc_val, exc_tb)
exc_type: 异常类型 exc_val: 异常值 exc_tb:异常回溯追踪
下面我们来手动实现一个文件操作:
class OpenFile(object):
"""手写实现文件操作的上下文"""
def __init__(self, filename, method):
self.file = open(filename, method)
def __enter__(self):
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
|