from collections import defaultdict
class _DefaultFactory:
def __init__(self):
self.count = 0
def __call__(self):
self.count = self.count + 1
return self.count
default_factory = _DefaultFactory()
d = defaultdict(default_factory)
print(d['foo'])
print(d['bar'])
使用闭包是做不到的.
使用 top-level variable 就太脏了.
1
sww4718168 2018-10-06 13:11:27 +08:00
这是为了模拟枚举么?为什么不直接用 enum
|
2
ltoddy OP @sww4718168 看来你是没看懂呀, 看看我说的最后一行那句话.
|
3
binux 2018-10-06 15:16:11 +08:00
from collections import defaultdict
def _DefaultFactory(): count = [0] def wrap(): count[0] = count[0] + 1 return count[0] return wrap default_factory = _DefaultFactory() d = defaultdict(default_factory) print(d['foo']) print(d['bar']) |
4
zh826256645 2018-10-06 15:31:44 +08:00
from collections import defaultdict
def _DefaultFactory(): count = 0 def wrap(): nonlocal count count += 1 return count return wrap default_factory = _DefaultFactory() d = defaultdict(default_factory) print(d['foo']) print(d['bar']) 或者指明 count 不是 wrap()的局部变量 |
5
sww4718168 2018-10-06 15:33:06 +08:00
@ltoddy 只是好奇应用场景是什么。
|
6
ltoddy OP @zh826256645 emmmm, 我可能当时在用闭包的时候眼瞎了.
|
7
ltoddy OP @sww4718168 来,我编一个例子, 假设你有一个 key-value 的缓存基于 defaultdict 做的, 然后呢,
> defaultdict(default_factory) default_factory 是一个可以被 invoke 的对象, 你直接把他当作函数就好了. 然后呢, 当 miss key 之后,那个 default_factory 就会被调用一次, 这个样子的, 你可以在 __getitem__ 和 get() 函数中做点事情, 然后就可以计算缓存命中率了, 然后你得到命中率之后, 你搞点事情,来避免缓存击穿问题之类的. (我刚吃完饭回到宿舍,刚刚编的.) |
8
aijam 2018-10-07 03:18:20 +08:00
from collections import defaultdict
from itertools import count d = defaultdict(count(1).__next__) print(d['foo']) print(d['bar']) |
10
macsed 2018-10-07 09:22:40 +08:00 via iPhone
动态语言里面搞一个 XXXFactory,看来是连门都没入...
|
14
xpresslink 2018-10-08 15:06:54 +08:00
就实现这么个功能至于绕那么大弯么?就会这点玩意儿至于那么膨胀么?
from collections import UserDict class CntDict(UserDict): → def __init__(self): → → self.data = {} → → self.count = 0 → def __getitem__(self, key): → → if key not in self.data: → → → self.count = self.count + 1 → → → self.data[key]= self.count → → → return self.data[key] d = CntDict() print(d['foo']) print(d['bar']) print(d['xxx']) print(d) # 1 # 2 # 3 # {'foo': 1, 'bar': 2, 'xxx': 3} |