[python]单例模式的六种实现方式:模块/类装饰器/类绑定方法/__new__方法/元类/并发

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里的代码块,所以实现了单例模式.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值