`

Tornado中的单例模式(Singleton)

阅读更多
单例模式也是设计模式一书中介绍的23中设计模式之一。
Questions:
  • 1、@classmethod和@staticmethod 的用法与区别?
  • 2、Singleton的实现
  • 3、Singleton什么时候适合使用?

问题1、
引用

     A staticmethod is a method that knows nothing about the class or instance it was called on. It just gets the arguments that were passed, no implicit first argument. It is basically useless in Python -- you can just use a module function instead of a staticmethod.
     A classmethod, on the other hand, is a method that gets passed the class it was called on, or the class of the instance it was called on, as first argument. This is useful when you want the method to be a factory for the class: since it gets the actual class it was called on as first argument, you can always instantiate the right class, even when subclasses are involved. Observe for instance howdict.fromkeys(), a classmethod, returns an instance of the subclass when called on a subclass:

示例:
#!/usr/bin/env python
#-*-encoding:utf-8-*-
class Demo:

    def get(self,x):
        print 'self and x is (%s,%s)'%(self,x)

    @classmethod
    def instance(cls,x):
        print 'cls and x Is (%s,%s)'%(cls,x)

    @staticmethod
    def static(x):
        print 'self and x is %s'%x

def main():
    demo = Demo()
    x=1
    demo.get(x)
    demo.instance(x)
    demo.static(x)
    Demo.instance(x)
    Demo.static(x)

if __name__=="__main__":
    main()

Result:

self and x is (<__main__.Demo instance at 0x109d44680>,1)
cls and x Is (__main__.Demo,1)
x is 1
cls and x Is (__main__.Demo,1)
x is 1

引用

     Below is the usual way an object instance calls a method. The object instance, a, is implicitly passed as the first argument.
     With classmethods, the class of the object instance is implicitly passed as the first argument instead ofself.
     With staticmethods, neither self (the object instance) nor cls (the class) is implicitly passed as the first argument.

    @staticmethod function is nothing more than a function defined inside a class. It is callable without instantiating the class first. It’s definition is immutable via inheritance.
    @classmethod function also callable without instantiating the class, but its definition follows Sub class, not Parent class, via inheritance. That’s because the first argument for @classmethod function must always be cls (class).


classmethod可以通过类实例调用,staticmethod只能通过类名调用

Say function a() is defined in Parent Class, while Sub Class extends Parent Class
If function a() has @staticmethod decorator, Sub.a() still refers to definition inside Parent Class. Whereas,
If function a() has @classmethod decorator, Sub.a() will points definition inside Sub Class.
继承的时候staticmethod调用的是父类的方法
classmethod由于传入了cls,父类和子类是加以区分开的

问题2、
我们先看下tornado源码中的单例模式。
    @staticmethod
    def instance():
        """Returns a global IOLoop instance.
        Most single-threaded applications have a single, global IOLoop.
        Use this method instead of passing around IOLoop instances
        throughout your code.
        A common pattern for classes that depend on IOLoops is to use
        a default argument to enable programs with multiple IOLoops
        but not require the argument for simpler applications::
            class MyClass(object):

                def __init__(self, io_loop=None):

                    self.io_loop = io_loop or IOLoop.instance()
        """
        if not hasattr(IOLoop, "_instance"):
            with IOLoop._instance_lock:
                if not hasattr(IOLoop, "_instance"):
                    # New instance after double check
                    IOLoop._instance = IOLoop()
        return IOLoop._instance

    @staticmethod
    def initialized():
        """Returns true if the singleton instance has been created."""
        return hasattr(IOLoop, "_instance")

    def install(self):
        """Installs this IOloop object as the singleton instance.
        This is normally not necessary as `instance()` will create
        an IOLoop on demand, but you may want to call `install` to use
        a custom subclass of IOLoop.
        """
        assert not IOLoop.initialized()
        IOLoop._instance = self



demo示例:
class Demo(object):

    def __init__(self):
        pass

    @classmethod
    def instance(cls):
        if not hasattr(cls,'_instance'):
            cls._instance=cls()
        return cls._instance

    @staticmethod
    def static_instance():
        if not hasattr(Demo,'_instance'):
            Demo._instance=Demo()
        return Demo._instance

    def test(self):
        print 'This is a demo.'

class MiniDemo(Demo):


    def __init__(self):
        super(MiniDemo, self).__init__()

    def test(self):
        print 'A new story.'

MiniDemo.instance().test()
MiniDemo.static_instance().test()
Demo.instance().test()
Demo.static_instance().test()


A new story.
This is a demo.
This is a demo.
This is a demo.


问题3、

请思考?适用场景以及局限。

单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点。
class Singleton

{
     private static Singleton instance;
     private Singleton()
     {

     }
     public static Singleton GetInstance()
     {
          if(instance == null)
          {
               instance = new Singleton();
          }
          return instance;
     }
}

作为其他对象的雏形而存在的对象,以及系统全体只存在唯一一个的对象等,都要用到Singleton模式。

Others:

  • with
  • super的用法
  • threading.local()


参考资料:
https://fuhm.net/super-harmful/
http://docs.python.org/2/library/functions.html#super
http://docs.python.org/2/library/functions.html#classmethod
http://docs.python.org/2/library/functions.html#staticmethod
http://www.artima.com/weblogs/viewpost.jsp?thread=236275
http://apt-blog.net/constructors_with_different_arguments_in_python_multiinheri_class
http://stackoverflow.com/questions/8972866/correct-way-to-use-super-argument-passing
http://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python
分享到:
评论

相关推荐

    tornado中文文档

    tornado 官方文档中文翻译版本,epub格式,可在kindle,掌阅等平台观看。

    Tornado中文培训教程

    此外,GNU工具链如GCC和C++编译器也自动集成于Tornado目录树中。 综上所述,Tornado中文培训教程详细介绍了Tornado开发环境的各个方面,从其核心组件、开发工具、配置选项到实时系统特性和交叉开发流程,为学习者...

    Tornado使用指南(中文版)

    这种模式允许在一个单线程环境中处理多个并发连接,极大地提高了服务器的吞吐量。通过定义`@tornado.gen.coroutine`装饰器的函数和使用`yield`关键字,开发者可以轻松实现异步操作。 ### 2. Web服务器和路由 ...

    tornado中文

    安装完成后,开发者可以根据项目需求配置 Tornado 的各项参数,例如设置静态文件路径、开启调试模式等。 #### 五、Tornado 的典型应用场景 Tornado 非常适合构建以下类型的 Web 应用: - **实时推送应用**:如...

    tornado 多进程模式解析

    本文主要研究的是tornado 多进程模式的相关内容,具体如下。 官方文档的helloworld实例中的启动方法: if __name__ == __main__: application.listen(8888) # listen is a shortcut for bind and start ,这点看...

    Python Tornado 中文教程

    得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。我们开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 ...

    Tornado教程.pdf

    Tornado 在实时 Web 应用中的优势在于对长轮询和 WebSockets 的支持。长轮询是一种模拟实时推送的技术,服务器在客户端请求没有关闭时保持连接,直到有新数据才返回。WebSockets 则提供双向通信通道,一旦建立连接,...

    Tornado实战Demo全集

    在IT行业中,Python是一种广泛应用的编程语言,而Tornado是一个基于Python的Web服务器框架和异步网络库。这个“Tornado实战Demo全集”显然是一份面向初学者的资源,旨在帮助他们深入理解和掌握Tornado框架,特别是其...

    Introduction to tornado中文教程.epub

    Introduction to tornado中文教程,介绍tornado的中文资料,难得的好书,简单通俗,实用的手册

    Tornado 2.2 入门介绍 中文

    - **URL 路由**: 使用 `url()` 函数定义URL模式和对应的处理函数。 - **模板**: 使用 `.html` 或 `.tt` 文件编写,与Python代码结合生成动态页面。 - **异步操作**: 利用 `tornado.gen.coroutine` 和 `yield` ...

    tornado 4.0.1 python framework guide

    这种设计模式允许 Tornado 在单个线程中同时处理成千上万个并发连接,极大地提高了服务器的响应速度和吞吐量。 **1.3 协程(Coroutines)** 协程是 Tornado 中处理异步任务的主要方式之一。通过使用装饰器 `@gen....

    python基于Tornado实现,系统核心调度,可分布式扩展

    Tornado采用了一个事件驱动的设计,利用了Python的`asyncio`库(在Python 3中)或者`tornado.ioloop`(在Python 2中)。IOLoop是Tornado的核心,它是一个事件循环,监控和调度所有异步操作。你可以注册回调函数,当...

    tornado替换文件win7_and_win10.zip

    在“tornado替换文件win7_and_win10.zip”这个压缩包中,包含了用于替换的文件,可能包括Tornado库的特定版本或者其他依赖项。解压后,按照上述步骤替换原有的Tornado文件。如果遇到权限问题或系统保护,可能需要以...

    Introduction to tornado中文教程.mobi kindle版

    我们三个都因为Tornado的速度、简单和可扩展性而深深地爱上了它,在一些个人项目中尝试之后,我们将其运用到日常工作中。我们已经看到,Tornado在很多大型或小型的项目中提升了开发者的速度(和乐趣!),同时,其...

    tornado2.2 for win7

    安装完成后,用户需要进行环境变量配置,将Tornado的路径添加到PATH变量中,以便在命令行中直接调用相关工具。 四、VxWorks开发流程 1. **项目创建**:在Tornado 2.2的IDE中,用户可以创建新的VxWorks项目,选择...

    在tornado2.2.1下可以工作的sqlite3.7.17

    描述中提到的"可以在tornado2.2.1下工作"进一步强调了这个SQLite版本与Tornado特定版本的兼容性,这在开发过程中非常重要,因为不同软件版本之间的兼容性问题可能导致代码无法正常运行。Tornado的异步特性使得它在...

Global site tag (gtag.js) - Google Analytics