python面试题-2018.1.30

问题:如何实现单例模式?

  1. 通过new方法来实现单例模式。
class Singleton(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

变体:

class Singleton(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance

  1. 通过装饰器来实现单例模式
from functools import wraps


def singleton(cls):
    instances = {}

    @wraps(cls)
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return wrapper

  1. 通过元类来创建单例模式,因为元类是用于创建类对象的类,类对象创建实例对象时一定会调用call方法,因此在调用call时候保证始终只创建一个实例即可。
class Singleton(type):
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super(Singleton, cls).__call__(*args, **kwargs)
            return cls._instance


class Foo(object):
    __metaclass__ = Singleton

  1. 通过共享属性来实现单例模式(通过这种方式实现,只是两个对象有相同的属性,但是在实例化之后,one is two 将会返回False), 将所有实例的dict指向同一个字典,这样实例就共享相同的方法和属性。对任何实例的名字属性的设置,无论是在init中修改还是直接修改,所有的实例都会受到影响。不过实例的id是不同的。要保证类实例能共享属性,但不和子类共享。
class Singleton(object):
    _state = {}

    def __new__(cls, *args, **kwargs):
        orig = super(Singleton, cls).__new__(cls, *args, **kwargs)
        orig.__dict__ = cls._state
        return orig

  1. 使用模块, Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做:
# singleton.py
class Singleton(object):
    def foo(self):
        pass


my_singleton = Singleton()

变体:

# singleton.py
import sys


class Singleton(object):
    pass


sys.modules[__name__] = Singleton()
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,869评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,754评论 18 399
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,123评论 6 13
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,205评论 30 471
  • 今天甜点读书会的话题是镜头里的世界,一下为群内精彩讨论,文中附有群友拍摄照片,转载请注明甜点读书会: 摄影师的想法...
    云淡昊天阅读 609评论 0 3