导航
  • 报考
  • 备考
  • 政策

报考

备考

复习资料

政策

行业动态

分享|进阶Python之单例模式的使用场景

环球青藤·2019-10-22 13:09:57浏览57 收藏28

请输入下面的图形验证码

提交验证

预约成功

我知道了
摘要 当今世界充满了各种数据,而python是其中一种的重要组成部分。然而,若想其有所应用,我们需要对这些python理论进行实践。其中包含很多有趣的的过程,然后将其用于某些方面。其中一种单例模式的使用场景。今天环球网校的小编就来和大家讲讲单例模式的使用场景。

由于单例模式的特殊性,使得它具备整体性、统一性的优势,因此,它的使用场景大多数也是围绕这两点优势进行展开的,如果遇到以下场景,我们可以考虑是否能够使用单例模式来实现,

1、单例模式的使用场景——场景描述

做项目开发过程中,大多数岗位都会和数据打交道,无论是前端还是后端。假如,我们存储数据工具是SQL Server,我们需要通过host、user、passwd来连接数据库进行读取数据,这时候就需要一次认证,多次调用,请注意这句话,很关键。

2、单例模式的使用场景——普通模式

我们首先来实现一个连接SQL的类,

class SqlClient(object):
      def __init__(self, host, user, passwd):
            self.host = host
            self.user = user
            self.passwd = passwd
            self.register()
      def register(self):
            self.info = "{}--{}---{}".format(self.host, self.user, self.passwd)
      def select(self):
            print("SELECT * FROM {}".format(self.host))

SqlClient中有3个方法,__init__用于初始化参数,register是认证SQL客户端,select是执行SQL语句的操作。

到这里,我们完成了SQL的认证,后面我们会在不同的地方查找数据,也就是在多个地方需要调用SqlClient类的select方法,试想一下我们该怎么实现?

有两种方法:

反复实例化、反复认证

把实例化后的对象作为参数传入到每个用到select的函数里

先看第一种,

host = "10.293.291.19"
user = "admin"
passwd = "666666"
def use_data_1():
      sql_client = SqlClient(host, user, passwd)
      sql_client.select()
def use_data_2():
      sql_client = SqlClient(host, user, passwd)
      sql_client.select()
def use_data_3():
      sql_client = SqlClient(host, user, passwd)
      sql_client.select()
use_data_1()
use_data_2()
use_data_3()
# 输出
SELECT * FROM 10.293.291.19
SELECT * FROM 10.293.291.19
SELECT * FROM 10.293.291.19

可以看到,我们在use_data_1、use_data_2、use_data_3三处使用到了SQL选择工具,每一次我们都要重新实例化SqlClient,显然,这是很麻烦的。

然后再看一下第二种方式,

host = "10.293.291.19
"user = "admin"
passwd = "666666"
def use_data_1(sql_client):
      sql_client.select()
def use_data_2(sql_client):
      sql_client.select()
def use_data_3(sql_client):
      sql_client.select()
sql_client = SqlClient(host, user, passwd)
use_data_1(sql_client)
use_data_2(sql_client)
use_data_3(sql_client)

我们可以先对实例化SqlClient,然后作为参数传入到每一个用到SQL工具的地方。

这样看来显然比第一种要好很多,在代码简洁性方面比第一种方法优化了不少,但是,开发中我们应该意识到一个问题,尽量少传参数,尤其是链式调用的函数,只在其中某几个环境用到,我们却需要不断的把它当作参数一致往下传递,如果这样的话,我们会发现,我们会传递很多参数,例如下面这个示例,

host = "10.293.291.19"
user = "admin"
passwd = "666666"
def use_data_1(sql_client):
      sql_client.select()
      use_data_2(sql_client)
def use_data_2(sql_client):
      use_data_3(sql_client)
def use_data_3(sql_client):
      sql_client.select()
sql_client = SqlClient(host, user, passwd)
use_data_1(sql_client)

可以看到上述示例,use_data_1调用use_data_2,use_data_2调用use_data_3,而我们在use_data_1、use_data_3中需要用到SQL工具,但是在use_data_2这个中间环节用不到,但是为了让参数继续传递下去,sql_client却不得不作为use_data_2的一个入参。

3、单例模式的使用场景——单例模式

这时候我们就可以使用单例模式来轻松解决这个问题,我们只需要实例化一次用于认证,然后再每个位置调用即可,

class Singleton(object):
      def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                  orig = super(Singleton, cls)
                  cls._instance = orig.__new__(cls)
            return cls._instance
class SqlClient(Singleton):
      info = None
      def register(self, host, user, passwd):
            self.info = "{}--{}--{}".format(host, user, passwd)
      def select(self): 
            print(self.info)

我们通过继承Singleton实现SqlClient的单例模式,我们只需要调用register一次,用于认证客户端,然后后期每次重新实例化都是指向的同一个实例,也就是已经认证过的示例,我们后面任何其他地方调用的地方直接使用select方法即可,

def use_data_1():
      SqlClient().select()
def use_data_2():
      SqlClient().select()
def use_data_3():
      SqlClient().select()
SqlClient().register(host, user, passwd)
use_data_1()
use_data_2()
use_data_3()

依此可以发散思维一下,凡是类似的场景都可以考虑一下单例模式的使用场景。

当然,凡事既有优点就会有缺点,单例模式的使用场景也是,它可以实现系统的整体性和统一性,但是也不是在任何场景下都是适用的,例如,

多线程

可变对象

在这些场景下,它违背了单例模式单一性原则,而且很容易因此数据错误。

因此,使用单例模式之前需要考虑一下对应场景是否适合,如果适合,单例模式能够大大提高代码的效率,同时使得代码更加简洁,但是如果不适合而强行使用单例模式,那样会导致很多未知的问题。

以上就是单例模式的使用场景。可能在刚讲解完这一实际应用之后,大家的印象还很模糊,不如打开电脑,那正好现在就上手操作一下,试一试吧!也许你还会发现更多python应用为您带来的乐趣环球网校的小编在这里希望这些信息可以对您有所帮助。

展开剩余
资料下载
历年真题
精选课程
老师直播

注册电脑版

版权所有©环球青藤All Rights Reserved