Python攻克之路-单例模式

单例模式
实例化

[root@node2 class2]# cat dan.py 
#!/usr/local/python3/bin/python3
class Foo:
    def __init__(self,name, age):
        self.name = name
        self.age = age
obj = Foo()  #obj对象,obj也成为Foo类的实例,这个过程也叫实例化

单例模式的实现:永远只使用一份实例(对象)

[root@node2 class2]# cat dan.py
#!/usr/local/python3/bin/python3
class Foo:
    def __init__(self,name, age):
        self.name = name
        self.age = age
    def show(self):
        print(self.name,self.age)

v = None   
while True:
    if v:   #第一次v是None,走else,v=Foo()创建了一个对象,第二次循环时,v已经有值
        v.show()  #执行show时,永远只使用同一个对象
    else:
        v = Foo('reid',23)
        v.show()

优化:以上方法依赖于一个全局变量

[root@node2 class2]# cat dan.py
#!/usr/local/python3/bin/python3
class Foo:
    __v = None

    @classmethod
    def get_isinstance(cls):  #cls代指Foo类
        if cls.__v:
            return cls.__v
        else:
            cls.__v = Foo() #给cls.__v赋值一个Foo对象
            return cls.__v
obj = Foo.get_isinstance()
# 如果使用单例模式,就不要使用类加括号,第一次执行时使用执行get_isinstance方法,__v是None,
  这时执行else,cls.__v = Foo()创建一个对象,这个对象再赋值给__v,再return cls.__v的值,此
  时obj就是刚创建的对象,当obj = Foo.get_isinstance()执行完后,__v是第一次执行时创建的对
  象

[root@node2 class2]# cat dan.py
#!/usr/local/python3/bin/python3
class Foo:
    __v = None

    @classmethod
    def get_isinstance(cls):
        if cls.__v:
            return cls.__v
        else:
            cls.__v = Foo()
            return cls.__v
obj1 = Foo.get_isinstance()
print(obj1)
obj2 = Foo.get_isinstance()
print(obj2)
obj3 = Foo.get_isinstance()
print(obj3)
[root@node2 class2]# python3 dan.py 
<__main__.Foo object at 0x7fe8c01ce4a8>    #三个实例都是一样的,实现使用同一对象
<__main__.Foo object at 0x7fe8c01ce4a8>
<__main__.Foo object at 0x7fe8c01ce4a8>
优点:
a. 在内存中的对象只需要创建一份

  

database场景使用
描述:连接数据库,对数据库做操作,实际上连接时的操作是很耗时间的,假设连接上数据库后,需要做的操作是10秒,可能连接的过程就要花费8秒的时间,执行的过程只需要2秒
  一般,有一个数据库的连接池,机器启动后,程序就主动去连接,假设默认创建5个链接,相当于还没发出连接请求,这5个通道就已经创建了,这样,每次操作都使用线程的通道就可以了,拿一个执行一个,如果并发数达到5后,就表明5个连接数都用完了,再有新的请求就处于等待,之前的5个,那个先执行完,就把它放回连接池中,新的请求再使用它
  程序运行起来,第一个用户请求来,应该利用原来的5个连接池,无论多少个用户请求来,数据库的连接池中的数量都是固定的,不会增加
  如果连接池是一个类,每次来请求,都是执行这个类的一个方法,通过这个类创建对象的方法,无论多少个人来都是使用同一个对象,对象都是同一个,对象又叫实例,所以在程序中,可以把这个类写成是单例模式,每次请求都使用同一实例做操作


tornado使用
安装tornado模块

[root@node2 class2]# pip3 install tornado --trusted-host pypi.douban.com
        import _ssl             # if we can't import it, let the error propagate
    ModuleNotFoundError: No module named '_ssl'     ##ssl问题
[root@node2 class2]# yum install openssl openssl-devel

重新编译python3

[root@node2 ~]# cd Python-3.6.5
[root@node2 Python-3.6.5]# ./configure --prefix=/usr/local/python3
[root@node2 Python-3.6.5]# make
[root@node2 Python-3.6.5]# make install

重新安装

[root@node2 class2]# pip3 install tornado --trusted-host pypi.douban.com
Collecting tornado
  Downloading http://pypi.doubanio.com/packages/cf/d1/3be271ae5eba9fb59df63c9891fdc7d8044b999e8ac145994cdbfd2ae66a/tornado-5.0.2.tar.gz (506kB)
    100% |████████████████████████████████| 512kB 2.1MB/s 
Installing collected packages: tornado
  Running setup.py install for tornado ... done
Successfully installed tornado-5.0.2

web程序

[root@node2 class2]# cat web.py 
#!/usr/local/python3/bin/python3
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        import time
        self.write(str(time.time()))

application = tornado.web.Application([
    (r"/index", MainHandler),
    ])

if __name__ == "__main__":
    application.listen(9999)                  ##使用单例模式,运行起来就监听9999端口
    tornado.ioloop.IOLoop.instance().start()  #ioloop是一个类,start就永远运行
[root@node2 class2]# python3 web.py

    

 

 

posted @ 2018-05-05 21:19  Reid21  阅读(162)  评论(0编辑  收藏  举报