Encontré algo como esto en un proyecto de código abierto. Los métodos que modifican los atributos de la instancia devuelven una referencia a la instancia. ¿Cuál es el propósito de esta construcción?
class Foo(object):
def __init__(self):
self.myattr = 0
def bar(self):
self.myattr += 1
return self
python
method-chaining
nate c
fuente
fuente
Respuestas:
Es para permitir el encadenamiento.
Por ejemplo:
Ahora puedes decir:
fuente
Como mencionan @Lie Ryan y @Frank Shearar, eso se llama una "interfaz fluida", pero ese patrón ha existido durante mucho tiempo.
La parte controvertida de ese patrón es que en OO, tiene un estado mutable, por lo que un método vacío tiene una especie de valor de retorno implícito
this
, es decir, el objeto con estado actualizado es una especie de valor de retorno.Entonces, en un lenguaje OO con estado mutable, estos dos son más o menos equivalentes:
...Opuesto a
Así que he escuchado a personas en el pasado resistirse a las interfaces fluidas porque les gusta la primera forma. Otro nombre que he escuchado para "interfaz fluida" es "choque de trenes";)
Sin embargo, digo "más o menos equivalente" porque las interfaces fluidas agregan una arruga. No tienen que "devolver esto". Pueden "volver nuevo". Esa es una forma de lograr objetos inmutables en OO.
Entonces podría tener una clase A que sí (pseudocódigo)
Ahora, cada método devuelve un nuevo objeto, dejando el objeto inicial sin cambios. Y esa es una forma de entrar en objetos inmutables sin realmente cambiar mucho en su código.
fuente
new(...)
, eso perdería memoria.__init__
repetidamente introduce gastos generales también.La mayoría de los idiomas son conscientes del idioma de "retorno de sí mismo", y lo ignoran si no se usa en una línea. Sin embargo, es notable que en Python, las funciones regresan
None
por defecto.Cuando estaba en la escuela CS, mi instructor hizo un gran trato sobre la diferencia entre funciones, procedimientos, rutinas y métodos; muchas preguntas de ensayo sobre calambres en las manos se resolvieron con lápices mecánicos que se calentaron en mis manos sobre todo eso.
Baste decir que devolver self es la forma definitiva de OO de crear métodos de clase, pero Python permite múltiples valores de retorno, tuplas, listas, objetos, primitivas o Ninguno.
Encadenar, como lo expresaron, es simplemente poner la respuesta a la última operación en la siguiente, y el tiempo de ejecución de Python puede optimizar ese tipo de cosas. Las comprensiones de listas son una forma incorporada de esto. (¡Muy poderoso!)
Por lo tanto, en Python no es tan importante que cada método o función devuelva cosas, por lo que el valor predeterminado es Ninguno.
Hay una escuela de pensamiento de que cada acción en un programa debe informar su éxito, fracaso o resultado a su contexto u objeto de invocación, pero luego no estaban hablando de los requisitos DOD ADA aquí. Si necesita obtener comentarios de un método, continúe o no, pero trate de ser coherente al respecto.
Si un método puede fallar, debe devolver el éxito o el fracaso o generar una excepción para ser manejado.
Una advertencia es que si usa el modismo propio de retorno, Python le permitirá asignar todos sus métodos a variables y podría pensar que está obteniendo un resultado de datos o una lista cuando realmente está obteniendo el objeto.
Los lenguajes de tipo restrictivo gritan, gritan y se rompen cuando intenta hacer esto, pero los interpretados (Python, Lua, Lisp) son mucho más dinámicos.
fuente
En Smalltalk, cada método que no devuelve algo explícitamente tiene un "retorno propio" implícito.
Esto se debe a que (a) hacer que cada método devuelva algo hace que el modelo informático sea más uniforme y (b) es muy útil que los métodos se devuelvan a sí mismos. Josh K da un buen ejemplo.
fuente
Python
, cada método que no devuelve algo explícitamente, tiene un "retorno ninguno" implícito.Pros de devolver un objeto (
return self
)Ejemplo:
Estilo más popular en la comunidad de programación (creo).
Ventajas de mutar un objeto (no
return self
)return
para otros fines.fuente