Python ABC:注册与子类化 [英] Python ABCs: registering vs. subclassing

查看:110
本文介绍了Python ABC:注册与子类化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我正在使用python 2.7)python文档指示您可以将映射传递给内置的dict,它将将该映射复制到新的dict中:

(I am using python 2.7) The python documentation indicates that you can pass a mapping to the dict builtin and it will copy that mapping into the new dict:

http://docs.python.org/library/stdtypes. html#mapping-types-dict

我有一个实现Mapping ABC的类,但是失败了:

I have a class that implements the Mapping ABC, but it fails:

import collections
class Mapping(object):
    def __init__(self, dict={}): self.dict=dict
    def __iter__(self): return iter(self.dict)
    def __iter__(self): return iter(self.dict)
    def __len__(self): return len(self.dict)
    def __contains__(self, value): return value in self.dict
    def __getitem__(self, name): return self.dict[name]

m=Mapping({5:5})
dict(m)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: cannot convert dictionary update sequence element #0 to a sequence
collections.Mapping.register(Mapping)
dict(m)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: cannot convert dictionary update sequence element #0 to a sequence

但是,如果我的班级将集合归为一类,则可以正常工作:

However, if my class subclasses collections.Mapping then it works fine:

import collections
class Mapping(collections.Mapping):
    def __init__(self, dict={}): self.dict=dict
    def __iter__(self): return iter(self.dict)
    def __iter__(self): return iter(self.dict)
    def __len__(self): return len(self.dict)
    def __contains__(self, value): return value in self.dict
    def __getitem__(self, name): return self.dict[name]

m=Mapping({5:5})
dict(m)
# {5: 5}

我认为ABC的全部目的是允许注册的工作与子类化相同(无论如何,对于isinstance和issubclass).那么这是怎么回事?

I thought the whole point of the ABCs was to allow registration to work the same as subclassing (for isinstance and issubclass anyway). So what's up here?

推荐答案

注册并不能为您提供定义之外的缺失方法":实际上,注册是非侵入性关于您正在注册的类型-不会添加任何内容,不会删除任何内容,不会更改任何内容.它会影响isinstanceissubclass检查:仅此而已.

Registration does not give you the "missing methods" implemented on top of those you define: in fact, registration is non-invasive with respect to the type you're registering -- nothing gets added to it, nothing gets removed, nothing gets altered. It only affects isinstance and issubclass checks: nothing more, nothing less.

在必须定义自己的基础上,对ABC进行子类化可以并且确实为您提供了许多由ABC免费"实现的方法.

Subclassing an ABC can and does give you plenty of methods implemented "for free" by the ABC on top of those you're having to define yourself.

打算来丰富类的操作(如子类化)相比,完全非侵入式(如注册)操作的语义显然不能完全相同;因此,您对"ABC的整个要点"的理解是不完善的-ABC有 2 个要点,一个是通过分类(侵入性")获得的,一个是通过注册(非侵入性的)获得的.

The semantics of an operation that's totally non-invasive like registering, compared to those of an operation that's intended to enrich a class, like subclassing, obviously cannot be identical; so your understanding of "the whole point of the ABCs" is imperfect -- ABCs have two points, one obtained by subclassing ("invasive"), one by registering (non-invasive).

请注意,如果您已经拥有像原始Mapping这样的类,则可以始终进行乘法继承:class GoogMapping(Mapping, collections.Mapping): ...与直接从collections.Mapping继承Mapping的结果相同-一种新的类型使用 collections.Mapping添加的所有辅助方法.

Note that you can always multiply-inherit if you already have a class like your original Mapping: class GoogMapping(Mapping, collections.Mapping): ... will give you the same results as inheriting Mapping directly from collections.Mapping -- a new type with all the auxiliary methods added by collections.Mapping.

这篇关于Python ABC:注册与子类化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆