6

(我使用的是 python 2.7)python 文档表明您可以将映射传递给 dict 内置函数,它将将该映射复制到新的 dict 中:

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

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

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

但是,如果我的类是 collections.Mapping 的子类,那么它可以正常工作:

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)。那么这里有什么?

4

2 回答 2

11

注册不会为您提供在您定义的那些之上实现的“缺失方法”:事实上,注册对于您正在注册的类型是非侵入性的——没有添加任何内容,没有任何内容被删除,没有任何内容被更改. 它只影响和检查:仅此而已,仅此而已isinstanceissubclass

将 ABC 子类化可以并且确实为您提供了许多由 ABC 在您必须自己定义的方法之上“免费”实现的方法。

完全非侵入性的操作(如注册)的语义与旨在丰富类的操作(如子类化)的语义显然不能相同;所以你对“ABCs的全部点”的理解是不完善的——ABCs有两点,一个是通过子类化(“侵入性”)获得的,一个是通过注册(非侵入性)获得的。

请注意,如果您已经有一个像原始类一样的类,则始终可以乘法继承Mappingclass GoogMapping(Mapping, collections.Mapping): ...将给您与Mapping直接继承相同的结果collections.Mapping——一个新类型所有辅助方法都由collections.Mapping.

于 2010-08-02T22:51:40.180 回答
0

啊,看起来 dict() 正在寻找 keys 方法......它不使用 ABC。

于 2010-08-02T23:04:22.523 回答