1.模块实现单例模式
# handler_log.py
import logging
from common.handle_config import conf_logging
from logging.handlers import TimedRotatingFileHandler
class log():
def __init__(self,name='root',file_name='basic.log',collector_level='DEBUG',file_level='DEBUG',system_level='INFO'):
self.name=name
self.file_name=file_name
self.collector_level=collector_level
self.file_level=file_level
self.system_level=system_level
# self.logger=self.create_log()
def create_log(self):
log=logging.getLogger(self.name)
log.setLevel(self.collector_level)
file_handler=TimedRotatingFileHandler(filename=self.file_name, when='D', interval=1, backupCount=7,encoding='utf-8')
file_handler.setLevel(self.file_level)
log.addHandler(file_handler)
system_handler=logging.StreamHandler()
system_handler.setLevel(self.system_level)
log.addHandler(system_handler)
log_format_file=logging.Formatter('%(asctime)s--%(levelname)s:%(message)s')
file_handler.setFormatter(log_format_file)
log_format_system=logging.Formatter('%(asctime)s - %(levelname)s [%(filename)s--%(lineno)d]: %(message)s')
system_handler.setFormatter(log_format_system)
return log
log=log(**conf_logging)
logger=log.create_log()
只要在其他模块导入handler_log.py中类的实例logger即可实现单例模式
# module.py
from common.handler_log import logger
上述代码只是为了演示单例模式,实际上logger不需要面向对象的思想实现.这是一种代码冗余,进一步说明了,在写代码时,并不是时刻都需要用面向对象的思想编程的,应该怎么方便怎么来.
2.类装饰器实现
from functools import wraps
def outer(cls):
obj=None
@wraps(cls)
def wrapper(*args,**kwargs):
nonlocal obj
if not obj:
obj=cls(*args,**kwargs)
return obj
return wrapper
@outer # Admin=outer(Admin)
class Admin(object):
def __init__(self):
...
@classmethod
def classmethod(cls):
...
obj1=Admin()
obj2=Admin()
print(obj1,obj2) # 输出<__main__.Admin object at 0x000001D7E21CB148> <__main__.Admin object at 0x000001D7E21CB148>
从打印的内存地址可以看出,obj1和obj2是同一个对象,因为内存地址相同嘛.
简单理解上述代码:第一次类的实例化,obj为None,自然会执行if not obj里的代码,并返回obj,此时外层的obj非None(闭包函数原理),第二次类的实例化,obj非None,自然不会走if not obj里的代码块,所以实现了单例模式.