一网打尽、详解面试最常被问到的几种 Python 设计模式(1)
事实上,任何一个编程语言都可以使用设计模式,它可以保证代码的规范性,只是每一种语言的实现方式略有不同而已
今天我们聊聊 Python 面试中,常被问到的 5 种设计模式,它们是:单例模式、工厂模式、构建者模式、代理模式、观察者模式**。**
-
单例模式
-
工厂模式
-
构建者模式
-
代理模式
-
观察者模式
1. 单例模式
单例模式,是最简单常用的设计模式,主要目的是保证某一个实例对象只会存在一个,减少资源的消耗
Python 单例模式有很多实现方式,这里推荐下面 2 种
第 1 种,重写 __new__ 方法
定义一个实例变量,在 __new__ 方法中保证这个变量仅仅初始化一次
单例模式
class Singleton(object):
_instance = None
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
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。


二、Python必备开发工具
工具都帮大家整理好了,安装就可直接上手!
三、最新Python学习笔记
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

四、Python视频合集
观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

五、实战案例
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
六、面试宝典


简历模板
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)

插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/76297f91d14514672f4a1b141f32f260.png)

简历模板
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
[外链图片转存中…(img-tr1UPUd7-1711076929189)]
更多推荐



所有评论(0)