2012-06-23 11 views
7

Estoy pensando en una situación en la que tengo un objeto "Transacción", que tiene un buen número de propiedades a ella como la cuenta, importe, fecha, moneda, tipo, etc.objetos sin Comportamiento

nunca planea mutar estos puntos de datos, y la lógica de cálculo vivirá en otras clases. Mi pregunta es, ¿es pobre el diseño de Python crear instancias de miles de objetos solo para contener datos? Encuentro que es mucho más fácil trabajar con datos incrustados en una clase que tratar de incluirlo en una combinación de estructuras de datos.

Respuesta

8

No, esto está perfectamente bien. De hecho, Python tiene soporte para él en el collections módulo estándar:

from collections import namedtuple 

Transaction = namedtuple("Transaction", ["account", "amount"]) 

en lugar de class Transaction(object): etc. Tenga en cuenta que namedtuple es una especie de "fábrica de clase" y hay que pasarle el nombre de la clase siendo construido, como una cadena. No es necesario que sea el nombre al que vincula el resultado, pero hacerlo sigue siendo una buena idea. Los tipos de tuplas nombrados son análogos a los registros en Pascal o las estructuras en C: titulares de datos con miembros nombrados pero sin un comportamiento significativo por sí mismos.

Uso:

>>> t = Transaction(account="my private account", amount=+1000) 
>>> t 
Transaction(account='my private account', amount=1000) 
>>> t.amount 
1000 
>>> t.amount += 1 
Traceback (most recent call last): 
    File "<ipython-input-6-ae60188f2446>", line 1, in <module> 
    t.amount += 1 
AttributeError: can't set attribute 
+0

Buena respuesta y la forma en que lo haría. La única alternativa que puedo pensar si algunos campos fueran escasos sería un 'dict' (potencialmente guardado en' __slots__') –

+0

@JonClements: la estructura tendría que ser muy escasa para garantizar el uso de un 'dict', ya que aquellos sobreasignar en grandes cantidades (al menos 1/3, creo). –

+0

Sí, pero pensé en tirarlo por completo. Dado el caso de uso del OP, su respuesta (al menos para mí) es correcta y debe ser aceptada. –

1

Yo diría que todos los valores son objetos de todos modos. Digamos que en lugar de instancia de clase de transacción, tendría un diccionario {'nombre de transacción': [123, 'GBP', '12/12/12', 1234, 'en']}. Ahora este diccionario es nuevamente un objeto y la diferencia es que no era tu propia clase. Todo es un objeto de todos modos. El hecho de que algo sea un objeto no lo convierte automáticamente en voluminoso, grande, lento o lo que sea. Probablemente todavía necesitaría una consideración sobre estas transacciones de cuántos de esos objetos desea guardar en la memoria en un momento dado.

En mi opinión, se trata de un código de diseño claro. Digamos que ahora tienes un libro de clase que tiene un método de acción, aceptando objetos de transacción como un atributo. Cuando este método de acción usará las propiedades del objeto, sería mucho más claro que si estuviera refiriéndose a los elementos n-ésimo de una lista, por ejemplo.

El hecho de que sea una clase también le deja la oportunidad de modificar o agregar funcionalidad en el futuro. Por ejemplo, es posible que desee agregar el registro de todas las transacciones o retirar el método en algún momento.

+0

Veo su punto, pero el OP dice: "Nunca planeo mutar estos puntos de datos, y la lógica de cálculo vivirá en otras clases". –

+0

Obtuve eso, siempre pienso lo mismo y luego resulta que podría necesitar cambiar algo después de unas semanas. Estos fueron mis argumentos para responder a la pregunta "... ¿es pobre el diseño de Python para crear instancias de miles de objetos solo para almacenar datos ...?" La flexibilidad del desarrollo futuro es uno de ellos. – Damian

Cuestiones relacionadas