Pau*_*zer 26 python python-3.x
为了举例,让我们假设我想子类化dict并把所有的键都大写:
class capdict(dict):
def __init__(self,*args,**kwds):
super().__init__(*args,**kwds)
mod = [(k.capitalize(),v) for k,v in super().items()]
super().clear()
super().update(mod)
def __getitem__(self,key):
return super().__getitem__(key.capitalize())
def __setitem__(self,key,value):
super().__setitem__(key.capitalize(),value)
def __delitem__(self,key):
super().__detitem__(key.capitalize())
Run Code Online (Sandbox Code Playgroud)
这在一定程度上起作用,
>>> ex = capdict(map(reversed,enumerate("abc")))
>>> ex
{'A': 0, 'B': 1, 'C': 2}
>>> ex['a']
0
Run Code Online (Sandbox Code Playgroud)
但是,当然,仅适用于我记得要实现的方法,例如
>>> 'a' in ex
False
Run Code Online (Sandbox Code Playgroud)
不是想要的行为。
现在,填充可以从“核心”方法派生的所有方法的懒惰方式将混合在collections.abc.MutableMapping. 只是,它在这里不起作用。我认为是因为所讨论的方法(__contains__在示例中)已经由dict.
有没有办法吃我的蛋糕并吃掉它?一些魔法让MutableMapping只看到我已经覆盖的方法,以便它基于这些重新实现其他方法?
Ray*_*ger 27
你可以做什么:
这可能不会很好(即不是最干净的设计),但您可以先从MutableMapping继承,然后再从dict继承。
然后MutableMapping将使用您实现的任何方法(因为它们是查找链中的第一个):
>>> class D(MutableMapping, dict):
def __getitem__(self, key):
print(f'Intercepted a lookup for {key!r}')
return dict.__getitem__(self, key)
>>> d = D(x=10, y=20)
>>> d.get('x', 0)
Intercepted a lookup for 'x'
10
>>> d.get('z', 0)
Intercepted a lookup for 'z'
0
Run Code Online (Sandbox Code Playgroud)
更好的方法:
最简洁的方法(易于理解和测试)是从MutableMapping继承,然后使用常规 dict 作为基本数据存储(使用组合而不是继承)来实现所需的方法:
>>> class CapitalizingDict(MutableMapping):
def __init__(self, *args, **kwds):
self.store = {}
self.update(*args, **kwds)
def __getitem__(self, key):
key = key.capitalize()
return self.store[key]
def __setitem__(self, key, value):
key = key.capitalize()
self.store[key] = value
def __delitem__(self, key):
del self.store[key]
def __len__(self):
return len(self.store)
def __iter__(self):
return iter(self.store)
def __repr__(self):
return repr(self.store)
>>> d = CapitalizingDict(x=10, y=20)
>>> d
{'X': 10, 'Y': 20}
>>> d['x']
10
>>> d.get('x', 0)
10
>>> d.get('z', 0)
0
>>> d['w'] = 30
>>> d['W']
30
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1734 次 |
| 最近记录: |