He pasado algún tiempo buscando una guía sobre cómo decidir cómo almacenar datos y funciones en una clase de Python. Debo señalar que soy nuevo en OOP, por lo que respuestas como:

los atributos de datos corresponden a "variables de instancia" en Smalltalk, y para "miembros de datos" en C ++. (como se ve en http://docs.python.org/tutorial/classes.html

Déjame rascándome la cabeza. Supongo que lo que busco es un manual sobre OOP dirigido a programadores de python. Espero que la guía / manual también incluya algún tipo de glosario o definiciones, por lo que después de leer podría hablar inteligentemente sobre los diferentes tipos de variables disponibles. Quiero comprender los procesos de pensamiento detrás de decidir cuándo usar las formas de a, b, c y d en el siguiente código.

class MyClass(object):
    a = 0

    def __init__(self):
        b = 0
        self.c = 0
        self.__d = 0

    def __getd(self):
        return self.__d

    d = property(__getd, None, None, None)
1
Phil 12 sep. 2011 a las 00:40

2 respuestas

La mejor respuesta

a, b y c muestran diferentes ámbitos de variables. Es decir, estas variables tienen una visibilidad y un entorno diferentes en el que son válidas.

Al principio, debe comprender la diferencia entre una clase y un objeto. Una clase es un vehículo para describir un comportamiento genérico. Luego se crea un objeto basado en esa clase. Los objetos "heredan" todos los métodos de la clase y pueden definir variables que están vinculadas al objeto. La idea es que los objetos encapsulan algunos datos y el comportamiento requerido para trabajar en esos datos. Esta es la principal diferencia con la programación de procedimientos, donde los módulos solo definen el comportamiento, pero no los datos.

c ahora es una variable de instancia, lo que significa una variable que vive en el alcance de una instancia de MyClass. self siempre es una referencia a la instancia de objeto actual en la que se ejecuta el código actual. Técnicamente, __d funciona igual que c y tiene el mismo alcance. La diferencia aquí es que es una convención en Python que las variables y los métodos que comienzan con dos guiones bajos se deben considerar privados no deben ser utilizados por código fuera de la clase. Esto es necesario porque Python no tiene una manera de definir métodos y variables verdaderamente privados o protegidos como lo hacen muchos otros lenguajes.

b es una variable simple que solo es válida dentro del método __init__. Si la ejecución deja el método __init__, la variable b se recolectará como basura y ya no será accesible mientras c y __d sigan siendo válidos. Tenga en cuenta que b no se antepone con self.

Ahora a se define directamente en la clase. Eso lo convierte en una llamada variable de clase. Por lo general, se usa para almacenar datos estáticos. Esta variable es la misma en todas las instancias de la clase MyClass.

Tenga en cuenta que esta descripción está un poco simplificada y omite cosas como las metaclases y la diferencia entre funciones y métodos enlazados, pero tiene la idea ...

2
Holger Just 11 sep. 2011 a las 21:04
  1. a. es para variables compartidas por todas las instancias de MyClass
  2. si. es para una variable que existirá solo dentro de la función init.
  3. C. es para un atributo de la instancia específica de MyClass, y es parte de la interfaz externa de MyClass (es decir, no se sorprenda si algún otro programador juega con esta variable). La desventaja de usar "c" es que reduce su flexibilidad para realizar cambios en MyClass (en algún momento, alguien probablemente dependerá del hecho de que "c" existe y hace ciertas cosas, así que si usted decide reorganizar tu clase, deberás estar preparado para mantener "c" para siempre).
  4. __re. es para un atributo de la instancia específica MyClass, y es parte de la implementación interna de MyClass; se puede suponer que solo el código de MyClass leerá / escribirá este atributo.
  5. re. Hace que __d se vea de muchas maneras como c. Sin embargo, la ventaja de usar d con __d es que si, por ejemplo, d () se puede calcular desde algún otro atributo, sería posible eliminar el almacenamiento adicional de __d. Además, se asegura de que esto solo se lea externamente, no que se escriba externamente.
1
Michael Aaron Safyan 11 sep. 2011 a las 20:52