设计模式-享元模式-flyweight-python??

来源:互联网 发布:淘宝的实名认证怎么弄 编辑:程序博客网 时间:2024/06/03 17:38

def

使用共享对象可有效地支持大量的细粒度的对象。

usage

享元模式是一个非常简单的模式, 它可以大大减少应用程序创建的对象, 降低程序内存的占用, 增强程序的性能, 但它同时也提高了系统复杂性, 需要分离出外部状态和内部状态, 而且外部状态具有固化特性, 不应该随内部状态改变而改变, 否则导致系统的逻辑混乱。

code

import weakrefclass FlyweightMeta(type):    def __new__(mcs, name, parents, dct):        """        Set up object pool        :param name: class name        :param parents: class parents        :param dct: dict: includes class attributes, class methods,        static methods, etc        :return: new class        """        dct['pool'] = weakref.WeakValueDictionary()        return super(FlyweightMeta, mcs).__new__(mcs, name, parents, dct)    @staticmethod    def _serialize_params(cls, *args, **kwargs):        """        Serialize input parameters to a key.        Simple implementation is just to serialize it as a string        """        args_list = list(map(str, args))        args_list.extend([str(kwargs), cls.__name__])        key = ''.join(args_list)        return key    def __call__(cls, *args, **kwargs):        key = FlyweightMeta._serialize_params(cls, *args, **kwargs)        pool = getattr(cls, 'pool', {})        instance = pool.get(key)        if instance is None:            instance = super(FlyweightMeta, cls).__call__(*args, **kwargs)            pool[key] = instance        return instanceclass Card(object):    """The object pool. Has builtin reference counting"""    _CardPool = weakref.WeakValueDictionary()    """Flyweight implementation. If the object exists in the    pool just return it (instead of creating a new one)"""    def __new__(cls, value, suit):        obj = Card._CardPool.get(value + suit)        if not obj:            obj = object.__new__(cls)            Card._CardPool[value + suit] = obj            obj.value, obj.suit = value, suit        return obj    # def __init__(self, value, suit):    #     self.value, self.suit = value, suit    def __repr__(self):        return "<Card: %s%s>" % (self.value, self.suit)def with_metaclass(meta, *bases):    """ Provide python cross-version metaclass compatibility. """    return meta("NewBase", bases, {})class Card2(with_metaclass(FlyweightMeta)):    def __init__(self, *args, **kwargs):        # print('Init {}: {}'.format(self.__class__, (args, kwargs)))        passif __name__ == '__main__':    # comment __new__ and uncomment __init__ to see the difference    c1 = Card('9', 'h')    c2 = Card('9', 'h')    print(c1, c2)    print(c1 == c2, c1 is c2)    print(id(c1), id(c2))    c1.temp = None    c3 = Card('9', 'h')    print(hasattr(c3, 'temp'))    c1 = c2 = c3 = None    c3 = Card('9', 'h')    print(hasattr(c3, 'temp'))    # Tests with metaclass    instances_pool = getattr(Card2, 'pool')    cm1 = Card2('10', 'h', a=1)    cm2 = Card2('10', 'h', a=1)    cm3 = Card2('10', 'h', a=2)    assert (cm1 == cm2) != cm3    assert (cm1 is cm2) is not cm3    assert len(instances_pool) == 2    del cm1    assert len(instances_pool) == 2    del cm2    assert len(instances_pool) == 1    del cm3    assert len(instances_pool) == 0### OUTPUT #### (<Card: 9h>, <Card: 9h>)# (True, True)# (31903856, 31903856)# True# False
原创粉丝点击