def new(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = object.new(cls, *args, **kwargs)
return cls._instance
使用方式如下:
if name == ‘main’:
构建3个实例
instance1 = Singleton()
instance2 = Singleton()
instance3 = Singleton()
打印出实例的内存地址,判断是否是同一个实例
print(id(instance1))
print(id(instance2))
print(id(instance3))
第 2 种,闭包定义装饰器
使用闭包的方式定义一个单例装饰器,将类的定义隐藏到闭包函数中
def singleton(cls):
“”"
定义单例的装饰器(闭包)
:param cls:
:return:
“”"
_instance = {}
def _singleton(*args, **kargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kargs)
return _instance[cls]
return _singleton
使用上面装饰器的类,构建的实例都能保证单例存在
@singleton
class Singleton(object):
“”“单例实例”“”
def init(self, arg1):
self.arg1 = arg1
使用方式如下:
if name == ‘main’:
instance1 = Singleton(“xag”)
instance2 = Singleton(“xingag”)
print(id(instance1))
print(id(instance2))
需要注意的是,上面 2 种方式创建的单例并不适用于多线程
要保证多线程中构建的实例对象为单例,需要在 __new__ 函数中使用 threading.Lock() 加入同步锁
class Singleton(object):
“”"
实例化一个对象
“”"
锁
_instance_lock = threading.Lock()
def init(self):
pass
def new(cls, *args, **kwargs):
if not hasattr(Singleton, “_instance”):
with Singleton._instance_lock:
if not hasattr(Singleton, “_instance”):
Singleton._instance = object.new(cls)
return Singleton._instance
使用的时候,在线程任务中实例化对象,运行线程即可
def task(arg):
“”"
任务
:param arg:
:return:
“”"
instance = Singleton()
print(id(instance), ‘\n’)
if name == ‘main’:
3个线程
for i in range(3):
t = threading.Thread(target=task, args=[i, ])
t.start()
这样,就保证了多线程创建的实例是单例存在的,不会导致脏数据!
2. 工厂模式
以生产3种水果对象为例,定义 3 类水果,分别是:苹果、香蕉、橘子
定义一系列水果
class Apple(object):
“”“苹果”“”
def repr(self):
return “苹果”
class Banana(object):
“”“香蕉”“”
def repr(self):
return “香蕉”
class Orange(object):
“”“橘子”“”
def repr(self):
return “橘子”
工厂模式包含:简单工厂、工厂方法、抽象工厂
第 1 种,简单工厂
简单工厂是最常见的工厂模式,适用于简单的业务场景
首先,定义一个工厂类,创建一个静态方法,根据输入的类型,返回不同的对象
class FactorySimple(object):
“”“简单工厂模式”“”
@staticmethod
def get_fruit(fruit_name):
if ‘a’ == fruit_name:
return Apple()
elif ‘b’ == fruit_name:
return Banana()
elif ‘o’ == fruit_name:
return Orange()
else:
return ‘没有这种水果’
使用方式如下:
if name == ‘main’:
分别获取3种水果
输入参数,通过简单工厂,返回对应的实例
instance_apple = FactorySimple.get_fruit(‘a’)
instance_banana = FactorySimple.get_fruit(‘b’)
instance_orange = FactorySimple.get_fruit(‘o’)
第 2 种,工厂方法
工厂方法将创建对象的工作让相应的工厂子类去实现,保证在新增工厂类时,不用修改原有代码
首先,创建一个抽象公共工厂类,并定义一个生产对象的方法
import abc
from factory.fruit import *
class AbstractFactory(object):
“”“抽象工厂”“”
metaclass = abc.ABCMeta
@abc.abstractmethod
def get_fruit(self):
pass
接着,创建抽象工厂类的 3 个子类,并重写方法,创建一个实例对象并返回
class AppleFactory(AbstractFactory):
“”“生产苹果”“”
def get_fruit(self):
return Apple()
class BananaFactory(AbstractFactory):
“”“生产香蕉”“”
def get_fruit(self):
return Banana()
class OrangeFactory(AbstractFactory):
“”“生产橘子”“”
def get_fruit(self):
return Orange()
最后的使用方式如下:
if name == ‘main’:
每个工厂负责生产自己的产品也避免了我们在新增产品时需要修改工厂的代码,而只要增加相应的工厂即可
instance_apple = AppleFactory().get_fruit()
instance_banana = BananaFactory().get_fruit()
instance_orange = OrangeFactory().get_fruit()
print(instance_apple)
print(instance_banana)
print(instance_orange)
第 3 种,抽象工厂
如果一个工厂要生产多个产品,使用工厂方法的话,就需要编写很多工厂类,不太实用,使用抽象工厂就可以很好的解决这个问题
以川菜馆和湘菜馆炒两个菜,毛血旺和小炒肉为例
首先,创建川菜毛血旺、川菜小炒肉、湘菜毛血旺、湘菜小炒肉 4 个类
class MaoXW_CC(object):
“”“川菜-毛血旺”“”
def str(self):
return “川菜-毛血旺”
class XiaoCR_CC(object):
“”“川菜-小炒肉”“”
def str(self):
return “川菜-小炒肉”
class MaoXW_XC(object):
“”“湘菜-毛血旺”“”
def str(self):
return “湘菜-毛血旺”
class XiaoCR_XC(object):
“”“湘菜-小炒肉”“”
def str(self):
return “湘菜-小炒肉”
然后,定义一个抽象工厂类,内部定义两个方法,可以生成毛血旺和小炒肉
class AbstractFactory(object):
“”"
抽象工厂
既可以生产毛血旺,也可以生成小炒肉
“”"
metaclass = abc.ABCMeta
@abc.abstractmethod
def product_maoxw(self):
pass
@abc.abstractmethod
def product_xiaocr(self):
pass
接着,创建抽象工厂类的两个子类,川菜工厂和湘菜工厂,重写方法,然后创建对应的实例对象返回
class CCFactory(AbstractFactory):
“”“川菜馆”“”
def product_maoxw(self):
return MaoXW_CC()
def product_xiaocr(self):
return XiaoCR_CC()
class XCFactory(AbstractFactory):
“”“湘菜馆”“”
文末有福利领取哦~
👉一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
👉二、Python必备开发工具
👉三、Python视频合集
观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
👉 四、实战案例
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(文末领读者福利)
👉五、Python练习题
检查学习结果。
👉六、面试资料
我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
👉因篇幅有限,仅展示部分资料,这份完整版的Python全套学习资料已经上传
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
[外链图片转存中…(img-JlvYNSQP-1711076963601)]