假如某个类的实例比较耗费内存或者实例化的时候耗费较多的时间,因此想实现一个和实例属性相关的单例,不知道这么叫对不对,,,想达到的效果如下:
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
或者有什么其他更好的解决方法
1
ruanimal 2020-05-26 10:20:24 +08:00
搞个字典做 cache 就 ok 了啊
|
2
huazhaozhe OP @ruanimal 如果属性值较多那这个字典可能有好多层吧,,,,,而且有好几个这样的类他们属性不同就要写不同的代码和字典,所以有了这个想法
|
3
a719114136 2020-05-26 10:30:35 +08:00
重写 __eq__()方法,然后用 == 判断
|
4
ClericPy 2020-05-26 10:31:02 +08:00
Borg 模式? 缓存字典放到类属性里, 在 `__new__` 里做类似单例的事情
|
5
ClericPy 2020-05-26 10:33:47 +08:00
纠正下 #4
后半句说的是单例模式... new 里做的就是用元组 (attr1, attr2) 做 key 去缓存里找 上半句是说可以参考下 Borg 模式 |
6
cassidyhere 2020-05-26 10:36:26 +08:00
你需要创建缓存实例
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 |
7
islxyqwe 2020-05-26 10:42:08 +08:00
```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 |
8
Vegetable 2020-05-26 10:46:22 +08:00
楼上正解,直接 lru_cache 完美符合你的需求,同样入参的调用会被缓存
|
9
huazhaozhe OP @islxyqwe nice
|
10
huazhaozhe OP @islxyqwe 当有默认参数的时候有点小问题,他是根据传入参数来决定的
|
11
noparking188 2020-05-26 11:36:03 +08:00
如果是数据相关的话,或许可以用下 dataclasses
|
12
ruanimal 2020-05-26 11:48:39 +08:00
@huazhaozhe 字典可以用 tuple 做 key,这样多少个属性都可以。 如果使用单例,最终也是用 dict 来缓存的。
|
13
huazhaozhe OP @ruanimal 这样的话传入参数必须一样的顺序,否则就不是同一个 tuple
|
14
huazhaozhe OP @ruanimal 而且当有默认参数时也有点问题,不过也可以用了,上边有人说的 lru_cache 可以直接用
|