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。