2011-02-16 13 views
5

Aquí es el patrón que estoy pensando en usar:¿Hay algún 'truco' con este patrón de Python?

class Dicty(dict): 
    def __init__(self): 
     self.__dict__ = self 

d = Dicty() 
d.foo = 'bar' 
print d['foo'] 
>>> bar 
d['foo'] = 'baz' 
print d.foo 
>>> 'baz' 

En general, prefiero la semántica de acceso atributo de objeto sobre dict acceso get/set, pero hay algunas circunstancias en las que se requiere el acceso dict-como (por ejemplo, d['foo-bar'] = 'baz') y prefiero no tener métodos getter setter especiales para estos casos, por lo tanto, el comportamiento dual del objeto dict & al mismo tiempo con atributos compartidos.

¿Hay algún problema con el patrón anterior?

+1

Ver: http://stackoverflow.com/questions/3031219/python-recursively-access-dict-via-attributes-as-well-as-index-access –

+1

'isinstance (dict, object)'. No necesita heredar de 'object'. Y la implementación es más que hacky. También: posible duplicado de [Acceso a claves dict como un atributo en Python?] (Http://stackoverflow.com/questions/4984647/accessing-dict-keys-like-an-attribute-in-python) – delnan

+1

Objetos creados en este la manera puede ser escabechada sin problema pero los objetos creados en el estilo sugerido por la respuesta aceptada no pueden. –

Respuesta

6

Aquí está una manera menos "hacky" para lograr el mismo efecto:

class Dicty(dict): 
    def __getattr__(self, key): 
     return self[key] 

    def __setattr__(self, key, value): 
     self[key] = value

I piensan que su forma puede funcionar bien también, pero estableciendo el atributo __dict__ como que parece un estilo- dudoso bits sabio, y está obligado a plantear algunas preguntas si alguien más termina leyendo su código.

+4

Debería capturar y traducir 'KeyError' -' __getattr__' debe arrojar 'AttributeError'. –

+2

Si va a hacer eso, es mejor hacer '__getattr__ = __getitem__' y' __setattr__ = __setitem__'. Más simple, y una llamada de función menos. – kindall

+0

@kindall @PiotrLegnica: ¡Ambos hacen puntos excelentes (aunque mutuamente exclusivos)! ¡Gracias! :) – shang

3

No establecer self.__dict__. Llame al __init__(self, *args, **kwargs) en la superclase. Además, dict hereda de object por lo que no necesita especificarlo.

2

Un par de cosas. Una es si intentas utilizar un método de diccionario, como keys, no podrás obtenerlo ahora. Hubo algunos otros problemas con los que me encontré, como ser elegible y copiable.

Pero he implementado algo que hace esto sin esos problemas. Puedes verlo aquí, es la clase AttrDict en el dictlib.py module. Ese módulo también contiene una clase que puede ajustar otro objeto de estilo de asignación, en los casos en que no se puede subclasificar.

Cuestiones relacionadas