原型模式
应用情景
如果想根据现有对象复制出线的对象并进行修改,那么可以考虑原型模式
python 创建对象的7种方法
Point 类
class Point:
__slots__ = ("x","y")
def __init__(self,x,y):
self.x = x
self.y = y
原型模式实现
def test():
point1 = Point(1, 2)
#这种方式有风险
point2 = eval("{}({},{})".formate("Point", 2, 4))
point3 = getattr(sys.modules[__name__], "Point")(3,6)
point4 = globals()["Point"](4,8)
point5 = make_object(Point,5,10)
point6 = copy.deepcopy(point5) #经典原型创建方式
point6.x = 6
point6.y = 12
#此方法无需先克隆对象,直接用新参数创建对象,效率会高很多
point7 = point1.__class__(7,4)
def make_object(Class,*args,**kwargs)
return Class(*args, **kwargs)
单例模式
应用情景
在整个程序运行的过程中,如果某个类只应该有一个实例,可以通过单例模式来保证
单例模式的实现:
创建模块时,把全局状态放在私有变量中,并提供用于访问此变量的公开函数
例子
创建一个函数,用于返回含有货币汇率的字典(该字典以货币名称为键,以汇率为值)。这个函数可能被调用多次,但是大部分情况下,汇率数据只需要获取一次即可。
_URL = "http://......"
def get(refresh=False):
if refresh:
get.rates = {}
if get.rates:
return get.rates
with urllib.request.urlopen(_URL) as file:
for line in file :
line = line.rstrip().decode("utf-8")
if not line or line.startswith("#","Date"):
continue
name, currency, *rest = re.split(r"\s*,\s*",line)
key = "{} ({})".format(name,currency)
try:
get.rates[key] = float(rest[-1])
except ValueError as err:
print("error {}: {}".format(err, line))
return get.rates
#创建了rates的字典用于保存私有数据,并将该字典设置成get()的私有属性
get.rates = {}