我在 Jython 中遇到了一个奇怪的字典/映射解包行为。最初,在 SQLAlchemy 的上下文中,但我设法将其缩小到以下最小示例:
import collections
class CustomMapping(collections.MutableMapping):
def __init__(self):
self.storage = {}
def __setitem__(self, key, value):
self.storage[key] = value
def __getitem__(self, key):
print('Accessed CustomMapping instance for key %s' % key)
return self.storage[key]
def __delitem__(self, key):
del self.storage[key]
def __len__(self):
return len(self.storage)
def __iter__(self):
for key in self.storage:
yield key
def __str__(self):
return str(self.storage)
现在我运行这个测试代码:
print(dict(
name='test', _some_stuff='abc', more='def', **CustomMapping())
)
在 Python 2.7 中,我得到了我所期望的:
{'more': 'def', '_some_stuff': 'abc', 'name': 'test'}
但是在 Jython 2.7.0 中,我得到了这个:
已访问键名的 CustomMapping 实例
访问了键 _some_stuff 的 CustomMapping 实例
为更多键访问了 CustomMapping 实例
{'more': 'def', '_some_stuff': 'abc', 'name': 'test'}
在调试器中设置断点还可以确认,在解包过程中,外部字典中的每个键都会访问实例__getitem__
方法。CustomMapping
这非常令人费解,只发生在 Jython 中,对我来说就像一个错误。虽然上面的示例dict
用作外部函数,但任何其他函数都可以。
我希望有人可以阐明这种行为。在我的真实上下文中,这在我的 SQLAlchemy 驱动的应用程序中引起了一些讨厌的行为。任何帮助是极大的赞赏。