zoukankan      html  css  js  c++  java
  • 【编程思想】【设计模式】【结构模式Structural】享元模式flyweight

    Python版

    https://github.com/faif/python-patterns/blob/master/structural/flyweight.py

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    """
    *References:
    http://codesnipers.com/?q=python-flyweights
    
    *TL;DR80
    Minimizes memory usage by sharing data with other similar objects.
    """
    
    import weakref
    
    
    class 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 instance
    
    
    class 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)))
            pass
    
    
    if __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
    Python转载版
  • 相关阅读:
    Unity 简易的UI背景昼夜轮替效果
    UE4 射线拾取&三维画线
    基于地产的消费生态群构想
    Unity插件
    Android5.1设备无法识别exFAT文件系统的64G TF卡问题
    MBR和GPT概要学习
    Linux驱动基础:MSM平台AP/CP通信机制
    使用UE4/Unity创建VR项目
    Unity UGUI基础之InputField
    Android组件内核之间组件间通信方案(四)下篇
  • 原文地址:https://www.cnblogs.com/demonzk/p/9035437.html
Copyright © 2011-2022 走看看