多态映射类型
Polymorphic mapping type
Python 中是否有类似 dict 的多态类型?这就是我所说的多态的意思:考虑一个基本的 class 层次结构,其中包含一个 Animal
基础 class 和一些派生的 classes、Cat
、[=14] =],等等,让我们有神秘的映射类型 mystery_dict
mapping = mystery_dict({
Animal : 'foo',
Cat : 'bar',
Snake : 'baz',
Python : 'eggs',
Boa : 'spam'
})
现在,我希望以下几行为真:
mapping[Animal] == 'foo'
mapping[Cat] == 'bar'
mapping[Dog] == 'foo' # No Dog in mapping, take the base class Animal
mapping[Snake] == 'baz'
mapping[Boa] == 'spam'
mapping[Anaconda] == 'baz' # No Anaconda in mapping, take the base class Snake
我知道自 Python 3.4 以来我可以使用一堆 isinstance
或 "overload set" 和 functools.singledispatch
但在某些情况下,多态字典类型将是方便减少样板文件。这种类型是否存在于野外,还是我必须创建一个?当然,如果你有更好的选择,我会很高兴听到。
注意: 以防万一有人问这个问题,我的需求很简单,所以它不必处理多重继承。
这很简单,可以自己写:
from collections.abc import MutableMapping
class PolymorphicDict(MutableMapping):
def __init__(self, *args, **kwargs):
self._mapping = dict(*args, **kwargs)
def __getitem__(self, key):
for cls in key.__mro__:
if cls in self._mapping:
return self._mapping[cls]
raise KeyError(key)
def __delitem__(self, key):
del self._mapping[key]
def __setitem__(self, key, value):
self._mapping[key] = value
def __iter__(self):
return iter(self._mapping)
def __len__(self):
return len(self._mapping)
这使用class.__mro__
attribute列出当前对象的class层级,按照方法查找顺序(Method Resolution Order)。此序列包括当前 class 并列出所有 class 直到 object
.
演示:
>>> class Animal: pass
...
>>> class Cat(Animal): pass
...
>>> class Dog(Animal): pass
...
>>> class Snake(Animal): pass
...
>>> class Python(Snake): pass
...
>>> class Boa(Snake): pass
...
>>> class Anaconda(Snake): pass
...
>>> Anaconda.__mro__
(<class '__main__.Anaconda'>, <class '__main__.Snake'>, <class '__main__.Animal'>, <class 'object'>)
>>> mapping = PolymorphicDict({
... Animal : 'foo',
... Cat : 'bar',
... Snake : 'baz',
... Python : 'eggs',
... Boa : 'spam'
... })
>>> mapping[Animal]
'foo'
>>> mapping[Cat]
'bar'
>>> mapping[Dog]
'foo'
>>> mapping[Snake]
'baz'
>>> mapping[Boa]
'spam'
>>> mapping[Anaconda]
'baz'
但是您可能想看看 zope.component
;这使您可以 完全做到这一点 添加接口。它已将查找映射优化到非常高的程度,以将原则扩展到更大的对象映射注册表。
Python 中是否有类似 dict 的多态类型?这就是我所说的多态的意思:考虑一个基本的 class 层次结构,其中包含一个 Animal
基础 class 和一些派生的 classes、Cat
、[=14] =],等等,让我们有神秘的映射类型 mystery_dict
mapping = mystery_dict({
Animal : 'foo',
Cat : 'bar',
Snake : 'baz',
Python : 'eggs',
Boa : 'spam'
})
现在,我希望以下几行为真:
mapping[Animal] == 'foo'
mapping[Cat] == 'bar'
mapping[Dog] == 'foo' # No Dog in mapping, take the base class Animal
mapping[Snake] == 'baz'
mapping[Boa] == 'spam'
mapping[Anaconda] == 'baz' # No Anaconda in mapping, take the base class Snake
我知道自 Python 3.4 以来我可以使用一堆 isinstance
或 "overload set" 和 functools.singledispatch
但在某些情况下,多态字典类型将是方便减少样板文件。这种类型是否存在于野外,还是我必须创建一个?当然,如果你有更好的选择,我会很高兴听到。
注意: 以防万一有人问这个问题,我的需求很简单,所以它不必处理多重继承。
这很简单,可以自己写:
from collections.abc import MutableMapping
class PolymorphicDict(MutableMapping):
def __init__(self, *args, **kwargs):
self._mapping = dict(*args, **kwargs)
def __getitem__(self, key):
for cls in key.__mro__:
if cls in self._mapping:
return self._mapping[cls]
raise KeyError(key)
def __delitem__(self, key):
del self._mapping[key]
def __setitem__(self, key, value):
self._mapping[key] = value
def __iter__(self):
return iter(self._mapping)
def __len__(self):
return len(self._mapping)
这使用class.__mro__
attribute列出当前对象的class层级,按照方法查找顺序(Method Resolution Order)。此序列包括当前 class 并列出所有 class 直到 object
.
演示:
>>> class Animal: pass
...
>>> class Cat(Animal): pass
...
>>> class Dog(Animal): pass
...
>>> class Snake(Animal): pass
...
>>> class Python(Snake): pass
...
>>> class Boa(Snake): pass
...
>>> class Anaconda(Snake): pass
...
>>> Anaconda.__mro__
(<class '__main__.Anaconda'>, <class '__main__.Snake'>, <class '__main__.Animal'>, <class 'object'>)
>>> mapping = PolymorphicDict({
... Animal : 'foo',
... Cat : 'bar',
... Snake : 'baz',
... Python : 'eggs',
... Boa : 'spam'
... })
>>> mapping[Animal]
'foo'
>>> mapping[Cat]
'bar'
>>> mapping[Dog]
'foo'
>>> mapping[Snake]
'baz'
>>> mapping[Boa]
'spam'
>>> mapping[Anaconda]
'baz'
但是您可能想看看 zope.component
;这使您可以 完全做到这一点 添加接口。它已将查找映射优化到非常高的程度,以将原则扩展到更大的对象映射注册表。