充当**解包映射的类
如果没有子类化 dict,类需要被视为映射,以便可以将其传递给带有 **
的方法。
from abc import ABCMeta
class uobj:
__metaclass__ = ABCMeta
uobj.register(dict)
def f(**k): return k
o = uobj()
f(**o)
# outputs: f() argument after ** must be a mapping, not uobj
至少到了它抛出缺少映射功能的错误的程度,这样我就可以开始实施了。
我回顾了模拟容器类型,但简单地定义魔术方法没有效果,并且使用 ABCMeta 来覆盖它并将其注册为 dict 将断言验证为子类,但失败了 isinstance(o, dict)isinstance(o, dict)代码>.理想情况下,我什至不想使用 ABCMeta 。
Without subclassing dict, what would a class need to be considered a mapping so that it can be passed to a method with **
.
from abc import ABCMeta
class uobj:
__metaclass__ = ABCMeta
uobj.register(dict)
def f(**k): return k
o = uobj()
f(**o)
# outputs: f() argument after ** must be a mapping, not uobj
At least to the point where it throws errors of missing functionality of mapping, so I can begin implementing.
I reviewed emulating container types but simply defining magic methods has no effect, and using ABCMeta
to override and register it as a dict validates assertions as subclass, but fails isinstance(o, dict)
. Ideally, I dont even want to use ABCMeta
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
__getitem__()
和keys()
方法就足够了:The
__getitem__()
andkeys()
methods will suffice:如果您尝试创建映射(不仅仅是满足传递给函数的要求),那么您确实应该继承
collections.abc.Mapping
。如文档中所述,您需要实现只是:Mixin 将为您实现其他所有内容:
__contains__
、keys
、items
、values
、获取,
__eq__
和__ne__
。If you're trying to create a Mapping — not just satisfy the requirements for passing to a function — then you really should inherit from
collections.abc.Mapping
. As described in the documentation, you need to implement just:The Mixin will implement everything else for you:
__contains__
,keys
,items
,values
,get
,__eq__
, and__ne__
.通过挖掘源头可以找到答案。
当尝试使用带有
**
的非映射对象时,会出现以下错误:如果我们在 CPython 的源代码中搜索该错误,我们可以找到 导致引发该错误的代码:
PyDict_Update
实际上是dict_merge
,当dict_merge
返回负数时抛出错误。如果我们检查dict_merge
的源代码,我们可以看到是什么导致返回-1:关键部分是:
The answer can be found by digging through the source.
When attempting to use a non-mapping object with
**
, the following error is given:If we search CPython's source for that error, we can find the code that causes that error to be raised:
PyDict_Update
is actuallydict_merge
, and the error is thrown whendict_merge
returns a negative number. If we check the source fordict_merge
, we can see what leads to -1 being returned:The key part being:
使用数据类
更干净,最终证明数据类的使用质量更好,这也有助于将正确的对象返回给
keys
方法。Using dataclasses
Cleaner and ultimatelly turns out to be better in terms of quality, the usage of dataclass, which helps also return the correct object to
keys
method.