python 使用装饰器实现单例模式

1、装饰器

python中一切皆对象,同样函数也是一个对象。函数对象有一个__name__属性,可以查看函数的名字。
 

def demo():
    print("xxx")

print(demo.__name__)

output:
 demo

假设我们要增强函数demod的功能,比如在函数执行前自动打印日志,但又不希望改变demo()函数的定义,此时就用到了装饰器。
这种在代码运行期间动态增加功能的方式,称为装饰器(decorator)。Python的decorator可以用函数实现,也可以用类实现。

def log(func):
    def wrapper(*args, **kw):
        print 'call %s():' % func.__name__
        return func(*args, **kw)
    return wrapper
@log
def demo():
    print("xxx")

demo()


output:
call demo():
xxx

2、单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某个类只有一个实例存在。如某个程序的配置文件,程序可能通过一个Settings的类来读取配置文件的信息。如果在程序运行期间有很多地方需要用到配置文件的内容,也就是很多地方需要创建Settings的实例,这就导致刺痛中存在多个Settings的实例对象,这样会严重浪费内存资源。类似于这种情况,我们希望程序运行期间只存在一个实例对象。

 

3、装饰器来实现单例模式:

from functools import wraps

def Singleton(cls):
    _instance = {}
    @wraps(cls)
    def _singleton(*args, **kargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kargs)
        return _instance[cls]

    return _singleton

@Singleton
class Settings():
    """Docstring"""
    def __init__(self):
        self.a = "xxx"
        self.b = "xxx"


settings = Settings()
print(settings.a)
print(Settings.__name__)
print(Settings.__doc__)

output:
xxx
Settings
Docstring

代码中@wraps的作用:Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。写一个decorator的时候,最好在实现之前加上functools的wrap,它能保留原有函数的名称和docstring。

猜你喜欢

转载自blog.csdn.net/qq_35462323/article/details/82912027