2010-04-05 11 views
62

Usar get/set parece ser una práctica común en Java (por varias razones), pero casi no veo el código de Python que usa esto.¿Utiliza el patrón get/set (en Python)?

¿Por qué utilizar o evitar métodos get/set en Python?

+0

Greate responses from everyone. Es cierto que esta pregunta es una derivación de este http://stackoverflow.com/questions/1022970/getters-and-setters-code-smell-necessary-evil-or-cant-live-without-them-clos, sin embargo, parece que fui atacado por una horda de personas que lo miraban desde la perspectiva de la palabra "J". Gracias de nuevo por restaurar mi fe en la cordura ... –

+1

El contexto es importante, y aquí Python y Java son simplemente diferentes. (Sin embargo, eliminé Python del título porque usamos etiquetas para eso en SO.;) –

Respuesta

49

enlace interesante: Python is not Java :)

En Java, se tiene que utilizar captadores y definidores porque el uso de campos públicos no le da ninguna oportunidad de volver atrás y cambiar de opinión más tarde a la utilización de captadores y definidores. Por lo tanto, en Java, es mejor que elimines la tarea por adelantado. En Python, esto es una tontería, porque puedes comenzar con un atributo normal y cambiar de opinión en cualquier momento, sin afectar a los clientes de la clase. Por lo tanto, no escriba getters y setters.

+3

más setters/getters agregan costo de rendimiento, especialmente en Python. –

+2

Esto * no * supone una carga adicional para el diseñador de la clase, ya que las variables de instancia se vuelven implícitamente parte de la API pública de la clase. Al diseñar una clase, piense de manera explícita a qué variables de instancia desea acceder externamente frente a las que realmente son parte de la implementación de su clase. Prefijo los de implementación interna con un '_' inicial. Esta es la señal de advertencia de Python que, si la implementación cambia, esta variable también podría cambiar o incluso desaparecer por completo. De lo contrario, descubrirá que el conocimiento de la implementación se está escapando de su clase, por lo que es difícil cambiarlo más adelante. – PaulMcG

+8

@Nick D: No creo que los accesadores sean el lugar correcto para hacer optimizaciones de velocidad en Python. – wRAR

11

No, es unpythonic. La forma generalmente aceptada es usar atributos de datos normales y reemplazar los que necesitan una lógica de obtención/configuración más compleja con propiedades.

+11

+1: "Todos somos adultos aquí". El código es visible. "private" y "getter/setter" no crean ningún valor cuando se puede ver todo el código. –

22

Esto es lo que dice Guido van Rossum sobre eso en Masterminds of Programming

¿Qué quiere decir con "la lucha contra el lenguaje"?

Guido: Que por lo general significa que son tratando de continuar con sus hábitos que funcionado bien con un idioma diferente.

[...] La gente va a convertir todo en una clase, y convertir cada acceso a un método de acceso ,
cuando no sea realmente una cosa sabia que hacer en Python; tendrá un código más detallado que es
más difícil de depurar y corre mucho más lento. Usted conoce la expresión "Puede escribir FORTRAN en cualquier idioma?" Puedes escribir Java en cualquier idioma, también.

4

Su observación es correcta. Este no es un estilo normal de programación de Python. Los atributos son todos públicos, por lo que solo tiene que acceder (obtener, configurar, eliminar) como lo haría con los atributos de cualquier objeto que los tenga (no solo clases o instancias). ¡Es fácil saber cuándo los programadores Java aprenden Python porque su código Python se parece a Java usando la sintaxis de Python!

estoy totalmente de acuerdo con todos los críticos anteriores, especialmente @ enlace de Maximiliano al famoso artículo de Phillip y @ sugerencia de Max que cualquier cosa más compleja que la forma habitual de establecer (y conseguir) de clase e instancia de atributos es usar las propiedades (o Descriptores para generalizar aún más) para personalizar la obtención y configuración de atributos. (Esto incluye la posibilidad de añadir sus propias versiones personalizadas de privado, protegido, amigo, o cualquier política que desee si lo desea algo que no sea pública.)

Como una demostración interesante, en Core Python Programming (capítulo 13, sección 13.16), se me ocurrió un ejemplo de uso de descriptores para almacenar atributos en el disco en lugar de en la memoria. Sí, es una forma rara de almacenamiento persistente, pero no que muestran un ejemplo de lo que es posible!

Aquí hay otro post relacionado que puede resultar útil, así: Python: multiple properties, one setter/getter

91

en Python, sólo puede acceder el atributo directamente porque es pública:

class MyClass(object): 

    def __init__(self): 
     self.my_attribute = 0 

my_object = MyClass() 
my_object.my_attribute = 1 # etc. 

Si queremos hacer algo en el acceso o la mutación del atributo, puede utilizar properties:

class MyClass(object): 

    def __init__(self): 
     self._my_attribute = 0 

    @property 
    def my_attribute(self): 
     # Do something if you want 
     return self._my_attribute 

    @my_attribute.setter 
    def my_attribute(self, value): 
     # Do something if you want 
     self._my_attribute = value 

crucial, el c el código de lient sigue siendo el mismo

4

La respuesta breve a su pregunta es no, debe usar propiedades cuando sea necesario. Ryan Tamyoko proporciona la respuesta larga en su artículo Getters/Setters/Fuxors

El valor básico de tomar distancia de todo esto es que desea esforzarse para asegurarse de que cada línea de código tiene algún valor o significado para el programador. Los lenguajes de programación son para humanos, no para máquinas. Si tiene un código que parece no hacer nada útil, es difícil de leer o parece tedioso, entonces es muy probable que Python tenga alguna función de idioma que le permita eliminarlo.

-6

Nuestro maestro mostraron un ejemplo de la clase de explicar cuándo debemos utilizar las funciones de acceso.

class Woman(Human): 
    def getAge(self): 
     if self.age > 30: 
      return super().getAge() - 10 
     else: 
      return super().getAge() 
+0

No te di los votos a favor, pero pensé que entraría. El punto de la discusión es "¿por qué necesitamos get()/set() para acceder a las propiedades directamente en Python". En Java, hay características del lenguaje ... que hacen que esto sea deseable. En Python, no tanto. –

+5

Además de no responder realmente la pregunta, el ejemplo utilizado en esta respuesta es ofensivo. La afirmación de que su maestro lo usó no justifica su sexismo. – Touzen

Cuestiones relacionadas