2011-12-22 11 views
49

Sin la subclasificación dict, lo que tendría que ser considerado como un mapeo de una clase de modo que se puede pasar a un método con **clase Python que actúa como mapeo para desembalar **

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 

Al menos a la punto donde arroja errores de falta de funcionalidad de mapeo, por lo que puedo comenzar a implementar.

Revisé la emulación de tipos de contenedores, pero la simple definición de métodos mágicos no tiene ningún efecto, y el uso de ABCMeta para anular y registrarlo como un dict valida las afirmaciones como subclase, pero falla isinstance (o, dict). Idealmente, ni siquiera quiero usar ABCMeta.

Respuesta

66

Los métodos __getitem__() y keys() serán suficientes:

>>> 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

Si usted está tratando de crear una asignación - no sólo satisfacer los requisitos para pasar a una función - entonces usted realmente debería heredar de collections.Mapping. Como se describe en el documentation, es necesario implementar simplemente:

__getitem__ 
__len__ 
__iter__ 

El Mixin pondrá en marcha todo lo demás para usted: __contains__, keys, items, values, get, __eq__ y __ne__.

+0

fuera del alcance, pero tiene relevancia y es informativo, gracias – dskinner

Cuestiones relacionadas