python基础-9.2 单例模式

设计模式

一、单例模式

单例,顾名思义单个实例。创建一个实例

链接池案例

1、单例=》只有一个实例

2、静态方法+静态字段

3、所有的实例中封装的内容相同时用单例模式

class ConnectionPoll:
    __instance = None #静态字段只有类可以访问

    def __init__(self):
        self.ip = "1.1.1.1"
        self.port = 3306
        self.pwd = 123
        self.username = "root"

        self.conn_list = [1,2,3,4,5,6,7]

    @staticmethod
    def get_instance():
        if ConnectionPoll.__instance:
            return ConnectionPoll.__instance
        else:
            #创建一个对象,并且赋值给__instance
            ConnectionPoll.__instance = ConnectionPoll()
            return ConnectionPoll.__instance
#静态方法类去访问
obj1 = ConnectionPoll.get_instance()
print(obj1)
obj2 = ConnectionPoll.get_instance()
print(obj2)
obj2= ConnectionPoll.get_instance()
print(obj2)

---------------------------
<__main__.ConnectionPoll object at 0x000002FEC59D42E8>
<__main__.ConnectionPoll object at 0x000002FEC59D42E8>
<__main__.ConnectionPoll object at 0x000002FEC59D42E8>

学习单例之前,首先来回顾下面向对象的内容:

python的面向对象由两个非常重要的两个“东西”组成:类、实例

面向对象场景一:

如:创建三个游戏人物,分别是:

  • 苍井井,女,18,初始战斗力1000
  • 东尼木木,男,20,初始战斗力1800
  • 波多多,女,19,初始战斗力2500
# #####################  定义类  #####################
class Person:

    def __init__(self, na, gen, age, fig):
        self.name = na
        self.gender = gen
        self.age = age
        self.fight =fig

    def grassland(self):
        """注释:草丛战斗,消耗200战斗力"""

        self.fight = self.fight - 200

# #####################  创建实例  #####################

cang = Person('苍井井', '', 18, 1000)    # 创建苍井井角色
dong = Person('东尼木木', '', 20, 1800)  # 创建东尼木木角色
bo = Person('波多多', '', 19, 2500)      # 创建波多多角色

创建实例

面向对象场景二:

如:创建对数据库操作的公共类

# #### 定义类 ####

class DbHelper(object):

    def __init__(self):
        self.hostname = '1.1.1.1'
        self.port = 3306
        self.password = 'pwd'
        self.username = 'root'

    def fetch(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

    def create(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

    def remove(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

    def modify(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

# #### 操作类 ####

db = DbHelper()
db.create()

创建示例

实例:结合场景二实现Web应用程序

#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server


class DbHelper(object):

    def __init__(self):
        self.hostname = '1.1.1.1'
        self.port = 3306
        self.password = 'pwd'
        self.username = 'root'

    def fetch(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return 'fetch'

    def create(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return 'create'

    def remove(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return 'remove'

    def modify(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return 'modify'


class Handler(object):

    def index(self):
        # 创建对象
        db = DbHelper()
        db.fetch()
        return 'index'

    def news(self):
        return 'news'


def RunServer(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ['PATH_INFO']
    temp = url.split('/')[1]
    obj = Handler()
    is_exist = hasattr(obj, temp)
    if is_exist:
        func = getattr(obj, temp)
        ret = func()
        return ret
    else:
        return '404 not found'

if __name__ == '__main__':
    httpd = make_server('', 8001, RunServer)
    print "Serving HTTP on port 8001..."
    httpd.serve_forever()

Web应用程序实例

测试代码

对于上述实例,每个请求到来,都需要在内存里创建一个实例,再通过该实例执行指定的方法。

那么问题来了...如果并发量大的话,内存里就会存在非常多功能上一模一样的对象。存在这些对象肯定会消耗内存,对于这些功能相同的对象可以在内存中仅创建一个,需要时都去调用,也是极好的!!!

单例模式出马,单例模式用来保证内存中仅存在一个实例!!!

通过面向对象的特性,构造出单例模式:

#!/usr/bin/env python
# _*_ coding:utf-8 _*_


class ConnectionPoll:
    __instance = None

    def __init__(self):
        self.ip = "1.1.1.1"
        self.port = 3306
        self.pwd = 123
        self.username = "root"

        self.conn_list = [1,2,3,4,5,6,7]

    @staticmethod
    def get_instance():
        if ConnectionPoll.__instance:
            return ConnectionPoll.__instance
        else:
            ConnectionPoll.__instance = ConnectionPoll()
            return ConnectionPoll.__instance

obj1 = ConnectionPoll.get_instance()
print(obj1)
obj2 = ConnectionPoll.get_instance()
print(obj2)
obj2= ConnectionPoll.get_instance()
print(obj2)

通过面向对象的特性,构造出单例模式:
# ########### 单例类定义 ###########
class Foo(object):
  
    __instance = None
  
    @staticmethod
    def singleton():
        if Foo.__instance:
            return Foo.__instance
        else:
            Foo.__instance = Foo()
            return Foo.__instance
  
# ########### 获取实例 ###########
obj = Foo.singleton()

 对于Python单例模式,创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.singleton() 。

这样多个人链接服务器访问地址就会只在内存中拿一份了

 1 #!/usr/bin/env python
 2 #coding:utf-8
 3 from wsgiref.simple_server import make_server
 4 
 5 # ########### 单例类定义 ###########
 6 class DbHelper(object):
 7 
 8     __instance = None
 9 
10     def __init__(self):
11         self.hostname = '1.1.1.1'
12         self.port = 3306
13         self.password = 'pwd'
14         self.username = 'root'
15 
16     @staticmethod
17     def singleton():
18         if DbHelper.__instance:
19             return DbHelper.__instance
20         else:
21             DbHelper.__instance = DbHelper()
22             return DbHelper.__instance
23 
24     def fetch(self):
25         # 连接数据库
26         # 拼接sql语句
27         # 操作
28         pass
29 
30     def create(self):
31         # 连接数据库
32         # 拼接sql语句
33         # 操作
34         pass
35 
36     def remove(self):
37         # 连接数据库
38         # 拼接sql语句
39         # 操作
40         pass
41 
42     def modify(self):
43         # 连接数据库
44         # 拼接sql语句
45         # 操作
46         pass
47 
48 
49 class Handler(object):
50 
51     def index(self):
52         obj =  DbHelper.singleton()
53         print id(single)
54         obj.create()
55         return 'index'
56 
57     def news(self):
58         return 'news'
59 
60 
61 def RunServer(environ, start_response):
62     start_response('200 OK', [('Content-Type', 'text/html')])
63     url = environ['PATH_INFO']
64     temp = url.split('/')[1]
65     obj = Handler()
66     is_exist = hasattr(obj, temp)
67     if is_exist:
68         func = getattr(obj, temp)
69         ret = func()
70         return ret
71     else:
72         return '404 not found'
73 
74 if __name__ == '__main__':
75     httpd = make_server('', 8001, RunServer)
76     print "Serving HTTP on port 8001..."
77     httpd.serve_forever()
78 
79  Web应用实例-单例模式
web实例-单例模式
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 from wsgiref.simple_server import make_server
 4 
 5 class ConnectionPool:
 6 
 7     __instance = None
 8 
 9     def __init__(self):
10         self.ip = "1.1.1.1"
11         self.port = 3306
12         self.pwd = "123123"
13         self.username = 'xxxx'
14         # 去连接
15         self.conn_list = [1,2,3,4,5,6,7,8,9, 10]
16 
17     @staticmethod
18     def get_instance():
19         if ConnectionPool.__instance:
20             return ConnectionPool.__instance
21         else:
22             # 创建一个对象,并将对象赋值给静态字段 __instance
23             ConnectionPool.__instance = ConnectionPool()
24             return ConnectionPool.__instance
25 
26     def get_connection(self):
27         # 获取连接
28         import random
29         r = random.randrange(1,11)
30         return r
31 
32 def index():
33     # p = ConnectionPool()
34     # print(p)
35     p = ConnectionPool.get_instance()
36     conn = p.get_connection()
37     return "fuck u bitch   " + str(conn)
38 
39 def news():
40     return 'bitchbitchbitchbitch'
41 
42 def RunServer(environ, start_response):
43     start_response(status='200 OK', headers=[('Content-Type', 'text/html')])
44 
45     url = environ['PATH_INFO']
46     if url.endswith('index'):
47         ret = index()
48         return ret
49     elif url.endswith('news'):
50         ret = news()
51         return ret
52     else:
53         return "404"
54 
55 
56 if __name__ == '__main__':
57     httpd = make_server('', 8077, RunServer)
58     print("Serving HTTP on port 8008...")
59     httpd.serve_forever()
60 
61 Web应用实例-单例模式
web实例-单例模式

总结:单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费!!!

 

posted @ 2017-04-14 15:16  崔崔0624  阅读(175)  评论(0编辑  收藏  举报
TOP