跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Python 如何实现一个和属性值相关的单例?
未分類
31 5 月 2020

Python 如何实现一个和属性值相关的单例?

Python 如何实现一个和属性值相关的单例?

資深大佬 : huazhaozhe 3

假如某个类的实例比较耗费内存或者实例化的时候耗费较多的时间,因此想实现一个和实例属性相关的单例,不知道这么叫对不对,,,想达到的效果如下:

class Example():     def __init__(self, attr1=None, attr2=None):         self.attr1 = attr1         self.attr2 = attr2  instance1 = Example('attr1', 'attr2') instance2 = Example('attr1', 'attr2') instance3 = Example('attr3', 'attr4') instance4 = Example('attr1', 'attr3')  # 希望达到的效果 # instance1 is instance2 结果为 True # instance1 is instance3 结果为 False # instance1 is instance4 结果为 False 

或者有什么其他更好的解决方法

大佬有話說 (14)

  • 資深大佬 : ruanimal

    搞个字典做 cache 就 ok 了啊

  • 主 資深大佬 : huazhaozhe

    @ruanimal 如果属性值较多那这个字典可能有好多层吧,,,,,而且有好几个这样的类他们属性不同就要写不同的代码和字典,所以有了这个想法

  • 資深大佬 : a719114136

    重写 __eq__()方法,然后用 == 判断

  • 資深大佬 : ClericPy

    Borg 模式? 缓存字典放到类属性里, 在 `__new__` 里做类似单例的事情

  • 資深大佬 : ClericPy

    纠正下 #4

    后半句说的是单例模式… new 里做的就是用元组 (attr1, attr2) 做 key 去缓存里找

    上半句是说可以参考下 Borg 模式

  • 資深大佬 : cassidyhere

    你需要创建缓存实例
    python cookbook 里的例子:

    import weakref

    class Cached(type):
    def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.__cache = weakref.WeakValueDictionary()

    def __call__(self, *args):
    if args in self.__cache:
    return self.__cache[args]
    else:
    obj = super().__call__(*args)
    self.__cache[args] = obj
    return obj

    # Example
    class Spam(metaclass=Cached):
    def __init__(self, name):
    self.name = name

    >>> a = Spam(‘Guido’)
    >>> b = Spam(‘Diana’)
    >>> c = Spam(‘Guido’) # Cached
    >>> a is b
    False
    >>> a is c # Cached value returned
    True

  • 資深大佬 : islxyqwe

    “`python3
    from functools import lru_cache
    @lru_cache(None)
    class Example():
    def __init__(self, attr1=None, attr2=None):
    self.attr1 = attr1
    self.attr2 = attr2

    instance1 = Example(‘attr1’, ‘attr2’)
    instance2 = Example(‘attr1’, ‘attr2’)
    instance3 = Example(‘attr3’, ‘attr4’)
    instance4 = Example(‘attr1’, ‘attr3’)
    print(instance1 is instance2,instance1 is instance3,instance1 is instance4)
    “`
    结果:True False False

  • 資深大佬 : Vegetable

    上正解,直接 lru_cache 完美符合你的需求,同样入参的调用会被缓存

  • 主 資深大佬 : huazhaozhe

    @islxyqwe nice

  • 主 資深大佬 : huazhaozhe

    @islxyqwe 当有默认参数的时候有点小问题,他是根据传入参数来决定的

  • 資深大佬 : noparking188

    如果是数据相关的话,或许可以用下 dataclasses

  • 資深大佬 : ruanimal

    @huazhaozhe 字典可以用 tuple 做 key,这样多少个属性都可以。 如果使用单例,最终也是用 dict 来缓存的。

  • 主 資深大佬 : huazhaozhe

    @ruanimal 这样的话传入参数必须一样的顺序,否则就不是同一个 tuple

  • 主 資深大佬 : huazhaozhe

    @ruanimal 而且当有默认参数时也有点问题,不过也可以用了,上边有人说的 lru_cache 可以直接用

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具