2011-12-22 72 views
49

没有子字典,将一个类需要考虑的映射是什么,这样可以传递给方法有**蟒蛇类作为映射**拆包

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覆盖并将其注册为字典将断言验证为子类,但isinstance(o,dict)失败。理想情况下,我甚至不想使用ABCMeta。

回答

66

__getitem__()keys()方法就足够了:

>>> class D: 
     def keys(self): 
      return ['a', 'b'] 
     def __getitem__(self, key): 
      return key.upper() 


>>> def f(**kwds): 
     print kwds 


>>> f(**D()) 
{'a': 'A', 'b': 'B'} 
19

如果你想创建一个映射 - 不只是满足传递给函数的要求 - 那么你真的应该从collections.Mapping继承。正如documentation描述,你只是需要实现:

__getitem__ 
__len__ 
__iter__ 

mixin将实现一切你:__contains__keysitemsvaluesget__eq____ne__

+0

超出范围,但具有相关性和信息性,谢谢你 – dskinner 2011-12-23 17:26:14