gpt4 book ai didi

python - 为什么我不能在 collections.MutableMapping 的子类上对 __setitem__ 进行猴子修补

转载 作者:行者123 更新时间:2023-11-28 17:12:36 25 4
gpt4 key购买 nike

通常,我可以随意修改 monkey-patch 和 mock 方法:

from UserDict import DictMixin
class py2fake_dict(DictMixin):
def __setitem__(self, name, value):
raise AssertionError("Don't talk to me!")
def __delitem__(self, name):
pass
def __getitem__(self, name):
pass
def __iter__(self):
yield None
def __len__(self):
return 0

c = py2fake_dict()
c.__setitem__ = lambda name, value: 'All clear.'
# This is OK:
c[1] = 2

但是,如果有问题的方法在 MutableMapping 子类上,我不能:

from collections import MutableMapping
class py3fake_dict(MutableMapping):
def __setitem__(self, name, value):
raise AssertionError("Don't talk to me!")
def __delitem__(self, name):
pass
def __getitem__(self, name):
pass
def __iter__(self):
yield None
def __len__(self):
return 0

c = py3fake_dict()
c.__setitem__ = lambda name, value: 'All clear.'
# This hits the assertion!!!
c[1] = 2

作为 Python3 升级的一部分,我在从 UserDict.DictMixin 升级到 collections.MutableMapping 时在工作代码中发现了这一点。我将删除代码,或在将来使用子类,但我只想了解发生了什么。

最佳答案

您可以在类上使用猴子修补方法,但在 new-style class实例 上使用猴子修补魔术方法自从在 Python 2.2 中引入了新式类以来,它就没有用过。新式类是 object 及其后代,并且有很多原因(更好的性能、更少奇怪的边缘情况、支持新功能,如 superproperty setters, Python 3 compatibility),只要有可能,你应该更喜欢新式类而不是旧式类。

UserDict.DictMixin 是一个老式类。在实例上设置魔术方法仅适用于旧式类的实例。 collections.MutableMapping 是一个新风格的类。

在 Python 3 中,没有旧式类,因此您将不得不习惯只有在类型上设置时才有效的魔术方法。

关于python - 为什么我不能在 collections.MutableMapping 的子类上对 __setitem__ 进行猴子修补,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46595995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com