回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我制作了一个名为<code>CustomDict</code>的dict包装器,它由键和<code>CustomValues</code>组成。CustomValue定义了<code>__iadd__</code>(<code>+=</code>)操作。此操作将对象添加到名为<code>self.lines</code>的列表中</p>
<pre><code>class CustomValue:
def __init__(self):
self.lines = []
def __iadd__(self, line):
self.lines.append(line)
class CustomDict:
def __init__(self):
self.data = {}
def __getitem__(self, key):
if key not in self.data:
self.data[key] = CustomValue()
return self.data[key]
# this doesn't feel pythonic
def __setitem__(self, key, value):
pass
def main():
d = CustomDict()
d['key0'] += 'Line 1'
d['key0'] += 'Line 2'
d['key1'] += 'Line 3'
d['key1'] += 'Line 4'
print(d)
</code></pre>
<p>这是我在调试器中看到的调用<code>d['key0'] += 'Line 1'</code>后发生的情况:</p>
<pre><code>d.__getitem__('key0').__iadd__('Line 1')
d.__setitem__('key0', None)
</code></pre>
<p>正如您所看到的,我必须用<code>pass</code>定义<code>__setitem__</code>,因为这样调用时,参数<code>value</code>是<code>None</code>。现在它可以工作了,但我有一个对<code>__setitem__</code>的冗余调用。如果我删除并注释掉它,我会得到以下错误:</p>
<p><code>TypeError: 'CustomDict' object does not support item assignment</code></p>
<p>正确的做法是什么</p>
<p><strong>默认dict编辑</strong></p>
<p>基于<a href="https://stackoverflow.com/a/59819578/10732434">user2357112 supports Monica answer</a>我写了以下内容:</p>
<pre><code>import collections
class Key:
def __init__(self):
self.lines = []
def __iadd__(self, line):
self.lines.append(line)
def missing():
return Key()
d = collections.defaultdict(missing)
d['key0'] += 'Line 1'
print(d['key0'])
</code></pre>
<p>但问题是新密钥没有插入回defaultdict,print语句打印<code>None</code>。我做错了什么</p>
<p><strong>Dict子类编辑</strong></p>
<p>我使用<a href="https://stackoverflow.com/a/59819572/10732434">Jordan Brière's answer</a>检查了CustomDict中的结果,发现有一些冗余键。我写了一个<code>__repr__</code>测试:</p>
<pre><code>class CustomValue:
def __init__(self):
self.lines = []
def __iadd__(self, line):
self.lines.append(line)
return self
def __repr__(self):
return 'CustomValue {}, {}'.format(self.__hash__(), self.lines)
class CustomDict(dict):
def __missing__(self, key):
key = self[key] = CustomValue()
return key
def __repr__(self):
return '\n'.join(['{}: {}'.format(key, self[key]) for key in self])
def main():
d = CustomDict()
d['key0'] += 'Line 1'
d['key0'] += 'Line 2'
d['key1'] += 'Line 3'
d['key1'] += 'Line 4'
print(d)
</code></pre>
<p>其中打印:</p>
<pre><code>CustomValue 1090233, ['Line 1', 'Line 2']: CustomValue 1090233, ['Line 1', 'Line 2']
key0: CustomValue 1090233, ['Line 1', 'Line 2']
CustomValue 1090235, ['Line 3', 'Line 4']: CustomValue 1090235, ['Line 3', 'Line 4']
key1: CustomValue 1090235, ['Line 3', 'Line 4']
</code></pre>
<p>正如您所看到的,一些自定义值是键,这不是我想要的</p>