2009-04-27 20 views
11

Estoy desarrollando en python una clase de archivo que puede leer y escribir un archivo, que contiene una lista de coordenadas xyz. En mi programa, ya tengo una clase Coord3D para mantener las coordenadas xyz.Devolver un objeto vs devolver una tupla

Mi pregunta es relativa al diseño de un método getCoordinate (index). ¿Debo devolver una tupla de flotadores o un objeto Coord3D?

En el primer caso, obtengo un acoplamiento muy bajo, pero probablemente tenga que instanciar un objeto de Coord3D con los valores obtenidos de todos modos, aunque fuera de la clase de archivo. En el segundo caso, tendré la clase de archivo estrechamente acoplada con la clase Coord3D.

Tenga en cuenta que creo que no hay una gran diferencia entre las dos soluciones, pero me gustaría leer su respuesta y la razón detrás de ello.


Editar: para resumir las respuestas que tenemos hasta ahora, parece que no hay elección bien definida. Se ha dicho (apropiadamente) que python no es Java, y no necesita una clase especializada para todo solo porque lo necesita por arquitectura de lenguaje. En mi caso, sin embargo, tengo las siguientes condiciones:

  1. Estoy trabajando en una biblioteca, donde el objeto de Coord3D se utiliza como está. Usarlo aumentaría la cohesión de mi biblioteca, ya que los tipos de datos se usarán de manera uniforme.
  2. El objeto Coord3D tiene estado y comportamiento. De hecho, el objeto Coord3D agrega las coordenadas y las unidades en una sola entidad. Las operaciones entre los objetos de Coord3D tendrán en cuenta las unidades potencialmente diferentes y actuarán en consecuencia.
  3. Puedo poner código de control de centralización en la instanciación de clase Coord3D para rechazar, por ejemplo, matrices de longitud 4 o unidades no. Si utilizo una tupla, no puedo realizar esta comprobación. Además, si un método acepta un Coord3D, se garantiza que está bien formado desde el principio (puede estar en negrita y comprobar si es instancia, o verificar la interfaz). Una tupla puede contener datos no válidos. Aunque el enfoque de pitón a la gestión de errores se realizará, siempre que ocurra el problema, una clase de prevención que yo tenga un coordenadas XYZ hecha de tres cuerdas es de alguna manera beneficiosa (corrígeme si mal, por favor)

Por otro lado, el uso de una tupla tiene las siguientes ventajas:

  1. Menos ocupación de recursos, bastante crítico en caso de gran
  2. Más sencillo diseño. Más clases significa un diseño más complejo. Una tupla es un tipo de datos estándar que se entiende bien y se puede desempaquetar fácilmente. Una clase personalizada no es.
  3. Usando una tupla, la clase XYZFile está totalmente desacoplada del resto de la biblioteca (porque no usa el objeto Coord3D). Esto significa que puede reutilizarse totalmente como una entidad independiente.

otros comentarios muy bienvenidos!

Respuesta

1

Me he preguntado la misma pregunta, aunque al hacer cosas geometría 2D.

La respuesta que encontré para mí fue que si estaba planeando escribir una biblioteca más grande, con más funciones y otras cosas, adelante y devuelva el Punto, o en su caso el objeto de Coord3D. Si solo se trata de una implementación estrafalaria, la tupla te ayudará a avanzar más rápido. Al final, es solo lo que vas a hacer con él, y vale la pena el esfuerzo.

1

Si solo se va a usar en su aplicación, y si va a crear una instancia Coord3D con los valores de todos modos, simplemente devolvería una instancia Coord3D para ahorrarle el esfuerzo. Sin embargo, si tiene algún interés en hacer este portátil/general, devuelva una tupla.Será fácil crear un Coord3D todos modos, utilizando

c3d = Coord3D(*getCoordinate(index)) 

(suponiendo que su constructor es Coord3D.__init__(self, x, y, z))

+0

No estoy seguro de que me gusta esto.Parece exponer algunos detalles inútiles. Creo que sería mejor elegir una representación y atenerse a ella. –

2

Si otras personas (aparte de usted) usarán esta clase, me parece que devolver un objeto podría fomentar algún tipo de uniformidad en los tipos de datos. Si la clase Coord3D tiene un método o una propiedad para acceder a estas coordenadas como una tupla, a continuación, que todavía les da esa opción, si lo necesitan:

# get the object 
coord_obj = my_obj.getCoordinate(my_index) 
# get the tuple (for example, via a property named "coords") 
coord_tup = my_obj.getCoordinate(my_index).coords 
2

La pregunta más fundamental es "¿Por qué tienes clase Coord3D? " ¿Por qué no usar una tupla?

El consejo general que la mayoría de nosotros damos a Python n00bz es "no invente nuevas clases hasta que tenga que hacerlo".

¿Tiene su Coord3D métodos únicos? Quizás necesites una nueva clase. O, tal vez, solo necesita algunas funciones que operan en tuplas.

¿Su Coord3D tiene estado variable? Poco probable. Una tupla inmutable comienza a verse como una mejor representación que una nueva clase.

+0

En general, estoy de acuerdo con su me gusta. Sin embargo, las cosas son realmente más complejas. El Coord3D es omnipresente en mi código, también porque está asociado con una Unidad Unum. –

+0

Pensé que un mantra de Python era "Los espacios de nombres son una gran idea para bocina: ¡hagamos más de eso!". ¿No es mejor una clase mejor que un grupo de funciones relacionadas (que operan con tuplas) en este sentido? ¿Por qué tienes un requisito de estado para una clase? Por cierto, soy nuevo en Python, pero pensé que la idea de crear clases era algo bueno, no algo que debía evitarse. – Trent

+0

+1: Agregar clases agrega complejidad, así que evítelo a menos que haya beneficios reales (que no veo en este caso). – nikow

1

Devolver un objeto sería la mejor práctica y le daría un mejor diseño general del software. Recomendaría hacerlo

Pero aún así, tenga en cuenta que crear/devolver un objeto llevará más tiempo de procesamiento. Podría cambiar algo si lo hace esta operación mucho y en ese caso puede que tenga que pensar en ello ...

13

solución de compromiso: En lugar de una clase, hacer un Coord3D namedtuple y volver :-) que

Uso:

Coord3D = namedtuple('Coord3D', 'x y z') 

def getCoordinate(index): 
    # do stuff, creating variables x, y, z 
    return Coord3D(x, y, z) 

El valor de retorno puede ser utilizado exactamente como una tupla, y tiene las mismas propiedades de velocidad y de memoria, por lo que no se pierde ninguna generalidad. Pero también puede acceder a sus valores por nombre: si c es el resultado de getCoordinate(index), entonces puede trabajar con c.x, c.y, etc., para una mayor legibilidad.

(obviamente esto es un poco menos útil si su clase Coord3D necesita otra funcionalidad también)

[si no estás en python2.6, puede obtener namedtuples de la cookbook recipe]

+0

Importar colecciones para tener namedtuple en la última versión de Python también! – Omiod

2

Tomar una mira el Gameobjects library de Will McGugan. Tiene un Vector3 class que se puede inicializar con otro objeto Vector3, una tupla, valores flotantes individuales, etc. Creo que esto responderá a tu pregunta ... además puedes terminar usando solo su biblioteca ya que está optimizada y tiene mucha utilidad métodos ya

+0

Definitivamente vale la pena echarle un vistazo a esta clase ... Aprendí un montón de modismos pitónicos de creación de clases y métodos al echar un vistazo a su fuente (bastante extensa, pero muy completa). – heltonbiker

Cuestiones relacionadas