Python: Orientación a objetos

En ¿Qué es Python? ya comentábamos que Python es un lenguaje multiparadigma en el se podía trabajar con programación estructurada, como veníamos haciendo hasta ahora, o con programación orientada a objetos o programación funcional.

La Programación Orientada a Objetos (POO u OOP según sus siglas en inglés) es un paradigma de programación en el que los conceptos del mundo real relevantes para nuestro problema se modelan a través de clases y objetos, y en el que nuestro programa consiste en una serie de interacciones entre estos objetos.

Clases y objetos

Para entender este paradigma primero tenemos que comprender qué es una clase y qué es un objeto. Un objeto es una entidad que agrupa un estado y una funcionalidad relacionadas. El estado del objeto se define a través de variables llamadas atributos, mientras que la funcionalidad se modela a través de funciones a las que se les conoce con el nombre de métodos del objeto.

Un ejemplo de objeto podría ser un coche, en el que tendríamos atributos como la marca, el número de puertas o el tipo de carburante y métodos como arrancar y parar. O bien cualquier otra combinación de atributos y métodos según lo que fuera relevante para nuestro programa.

Una clase, por otro lado, no es más que una plantilla genérica a partir de la cuál instanciar los objetos; plantilla que es la que define qué atributos y métodos tendrán los objetos de esa clase.

Volviendo a nuestro ejemplo: en el mundo real existe un conjunto de objetos a los que llamamos coches y que tienen un conjunto de atributos comunes y un comportamiento común, esto es a lo que llamamos clase. Sin embargo, mi coche no es igual que el coche de mi vecino, y aunque pertenecen a la misma clase de objetos, son objetos distintos.

En Python las clases se definen mediante la palabra clave class seguida del nombre de la clase, dos puntos (:) y a continuación, indentado, el cuerpo de la clase. Como en el caso de las funciones, si la primera línea del cuerpo se trata de una cadena de texto, esta será la cadena de documentación de la clase o docstring.

class Coche:
    """Abstraccion de los objetos coche."""
    def __init__(self, gasolina):
        self.gasolina = gasolina
        print "Tenemos", gasolina, "litros"

    def arrancar(self):
        if self.gasolina > 0:
            print "Arranca"
        else:
            print "No arranca..."

    def conducir(self):
        if self.gasolina > 0:
            self.gasolina -= 1
            print "Quedan", self.gasolina, "litros"
        else:
            print "No se mueve..."

Lo primero que llama la atención en el ejemplo anterior es el nombre tan curioso que tiene el método __init__. Este nombre es una convención y no un capricho. El método __init__, con una doble barra baja al principio y final del nombre, se ejecuta justo después de crear un nuevo objeto a partir de la clase, proceso que se conoce con el nombre de instanciación. El método __init__ sirve, como sugiere su nombre, para realizar cualquier proceso de inicialización que sea necesario.

Como vemos el primer parámetro de __init__ y del resto de métodos de la clase es siempre self. Esta es una idea inspirada en Modula-3 y sirve para referirse al objeto actual. Este mecanismo es necesario para poder acceder a los atributos y métodos del objeto diferenciando, por ejemplo, una variable local mi_var de un atributo del objeto self.mi_var.

Si volvemos al método __init__ de nuestra clase Coche veremos cómo se utiliza self para asignar al atributo gasolina del objeto (self.gasolina) el valor que el programador especificó para el parámetro gasolina. El parámetro gasolina se destruye al final de la función, mientras que el atributo gasolina se conserva (y puede ser accedido) mientras el objeto viva.

Para crear un objeto se escribiría el nombre de la clase seguido de cualquier parámetro que sea necesario entre paréntesis. Estos parámetros son los que se pasarán al método __init__, que como decíamos es el método que se llama al instanciar la clase.

mi_coche = Coche(3)

Os preguntareis entonces cómo es posible que a la hora de crear nuestro primer objeto pasemos un solo parámetro a __init__, el número 3, cuando la definición de la función indica claramente que precisa de dos parámetros (self y gasolina). Esto es así porque Python pasa el primer argumento (la referencia al objeto que se crea) automágicamente.

Ahora que ya hemos creado nuestro objeto, podemos acceder a sus atributos y métodos mediante la sintaxis objeto.atributo y objeto.metodo():

>>> print mi_coche.gasolina
3
>>> mi_coche.arrancar()
Arranca
>>> mi_coche.conducir()
Quedan 2 litros
>>> mi_coche.conducir()
Quedan 1 litros
>>> mi_coche.conducir()
Quedan 0 litros
>>> mi_coche.conducir()
No se mueve…
>>> mi_coche.arrancar()
No arranca…
>>> print mi_coche.gasolina
0

Como último apunte recordar que en Python, como ya se comentó en repetidas ocasiones anteriormente, todo son objetos. Las cadenas, por ejemplo, tienen métodos como upper(), que devuelve el texto en mayúsculas o count(sub), que devuelve el número de veces que se encontró la cadena sub en el texto.

Herencia

Hay tres conceptos que son básicos para cualquier lenguaje de programación orientado a objetos: el encapsulamiento, la herencia y el polimorfismo.

En un lenguaje orientado a objetos cuando hacemos que una clase (subclase) herede de otra clase (superclase) estamos haciendo que la subclase contenga todos los atributos y métodos que tenía la superclase. No obstante al acto de heredar de una clase también se le llama a menudo «extender una clase».

Supongamos que queremos modelar los instrumentos musicales de una banda, tendremos entonces una clase guitarra, una clase batería, una clase bajo, etc. Cada una de estas clases tendrá una serie de atributos y métodos, pero ocurre que, por el mero hecho de ser instrumentos musicales, estas clases compartirán muchos de sus atributos y métodos; un ejemplo sería el método tocar.

Es más sencillo crear un tipo de objeto instrumento con las atributos y métodos comunes e indicar al programa que guitarra, batería y bajo son tipos de instrumentos, haciendo que hereden de instrumento.

Para indicar que una clase hereda de otra se coloca el nombre de la clase de la que se hereda entre paréntesis después del nombre de la clase:

class Instrumento:
    def __init__(self, precio):
        self.precio = precio

    def tocar(self):
        print "Estamos tocando musica"

    def romper(self):
        print "Eso lo pagas tu"
        print "Son", self.precio, "$$$"

class Bateria(Instrumento):
    pass

class Guitarra(Instrumento):
    pass

Como Bateria y Guitarra heredan de Instrumento, ambos tienen un método tocar y un método romper, y se inicializan pasando un parámetro precio. Pero, ¿qué ocurriría si quisiéramos especificar un nuevo parámetro tipo_cuerda a la hora de crear un objeto Guitarra? Bastaría con escribir un nuevo método __init__ para la clase Guitarra que se ejecutaría en lugar del __init__ de Instrumento.

Ahora bien, puede ocurrir en algunos casos que necesitemos sobreescribir un método de la clase padre, pero que en ese método queramos ejecutar el método de la clase padre porque nuestro nuevo método no necesite más que ejecutar un par de nuevas instrucciones extra. En ese caso usaríamos la sintaxis SuperClase.metodo(self, args); por ejemplo, para llamar al método __init__ de Instrumento desde Guitarra usaríamos Instrumento.__init__(self, precio)

Observad que en este caso si es necesario especificar el parámetro self.

Herencia múltiple

En Python, a diferencia de otros lenguajes como Java o C#, se permite la herencia múltiple, es decir, una clase puede heredar de varias clases a la vez. Por ejemplo, podríamos tener una clase Cocodrilo que heredara de la clase Terrestre, con métodos como caminar() y atributos como velocidad_caminar y de la clase Acuatico, con métodos como nadar() y atributos como velocidad_nadar. Basta con enumerar las clases de las que se hereda separándolas por comas:

class Cocodrilo(Terrestre, Acuatico):
    pass

En el caso de que alguna de las clases padre tuvieran métodos con el mismo nombre y número de parámetros las clases sobreescribirían la implementación de los métodos de las clases más a su derecha en la definición. En el siguiente ejemplo, como Terrestre se encuentra más a la izquierda, sería la definición de desplazar de esta clase la que prevalecería, y por lo tanto si llamamos al método desplazar de un objeto cocodrilo lo que se imprimiría sería «El animal anda».

class Terrestre:
    def desplazar(self):
        print "El animal anda"

class Acuatico:
    def desplazar(self):
        print "El animal nada"

class Cocodrilo(Terrestre, Acuatico):
    pass

c = Cocodrilo()
c.desplazar()

Polimorfismo

La palabra polimorfismo, del latín polys morphos (varias formas), se refiere a la habilidad de objetos de distintas clases de responder al mismo mensaje. Esto se puede conseguir a través de la herencia: un objeto de una clase derivada es al mismo tiempo un objeto de la clase padre, de forma que allí donde se requiere un objeto de la clase padre también se puede utilizar uno de la clase hija.

Python, al ser de tipado dinámico no impone restricciones a los tipos que se le pueden pasar a una función, por ejemplo, más allá de que el objeto se comporte como se espera: si se va a llamar a un método f del objeto pasado como parámetro, por ejemplo, evidentemente el objeto tendrá que contar con ese método. Por ese motivo, a diferencia de lenguajes de tipado estático como Java o C++, el polimorfismo en Python no es de gran importancia.

En ocasiones también se utiliza el término polimorfismo para referirse a la sobrecarga de métodos, término que se define como la capacidad del lenguaje de determinar qué método ejecutar de entre varios métodos con igual nombre según el tipo o número de los parámetros que se le pasa. En Python no existe sobrecarga de métodos (el último método sobreescribiría la implementación de los anteriores), aunque se puede conseguir un comportamiento similar recurriendo a funciones con valores por defecto para los parámetros o a la sintaxis *params o **params explicada en Python: Funciones, o bien usando decoradores (mecanismo que veremos más adelante).

Encapsulación

La encapsulación se refiere a impedir el acceso a determinados métodos y atributos de los objetos estableciendo así qué puede utilizarse desde fuera de la clase.

Esto se consigue en otros lenguajes de programación como Java utilizando modificadores de acceso que definen si cualquiera puede acceder a esa función o variable (public) o si está restringido el acceso a la propia clase (private).

En Python no existen los modificadores de acceso, y lo que se suele hacer es que el acceso a una variable o función viene determinado por su nombre: si el nombre comienza con dos guiones bajos (y no termina también con dos guiones bajos) se trata de una variable o función privada, en caso contrario es pública. Los métodos cuyo nombre comienza y termina con dos guiones bajos son métodos especiales que Python llama automáticamente bajo ciertas circunstancias, como veremos al final del artículo.

En el siguiente ejemplo sólo se imprimirá la cadena correspondiente al método público, mientras que al intentar llamar al método __privado Python lanzará una excepción quejándose de que no existe (evidentemente existe, pero no lo podemos ver porque es privado).

class Ejemplo:
    def publico(self):
        print "Publico"

    def __privado(self):
        print "Privado"

ej = Ejemplo()
ej.publico()
ej.__privado()

Este mecanismo se basa en que los nombres que comienzan con un doble guión bajo se renombran para incluir el nombre de la clase. Esto implica que el método o atributo no es realmente privado, y podemos acceder mediante una pequeña trampa:

ej._Ejemplo__privado()

En ocasiones también puede suceder que queramos permitir el acceso a algún atributo de nuestro objeto, pero que este se produzca de forma controlada. Para esto podemos escribir métodos cuyo único cometido sea este, métodos que normalmente, por convención, tienen nombres como getVariable y setVariable; de ahí que se conozcan también con el nombre de getters y setters.

class Fecha():
    def __init__(self):
        self.__dia = 1

    def getDia(self):
        return self.__dia

    def setDia(self, dia):
        if dia > 0 and dia < 31:
            self.__dia = dia
        else:
            print "Error"

mi_fecha = Fecha()
mi_fecha.setDia(33)

Esto se podría simplificar mediante propiedades, que abstraen al usuario del hecho de que se está utilizando métodos entre bambalinas para obtener y modificar los valores del atributo:

class Fecha(object):
    def __init__(self):
        self.__dia = 1

    def getDia(self):
        return self.__dia

    def setDia(self, dia):
        if dia > 0 and dia < 31:
            self.__dia = dia
        else:
            print "Error"

    dia = property(getDia, setDia)

mi_fecha = Fecha()
mi_fecha.dia = 33

Clases de «nuevo-estilo»

En el ejemplo anterior os habrá llamado la atención el hecho de que la clase Fecha derive de object. La razón de esto es que para poder usar propiedades la clase tiene que ser de «nuevo-estilo», clases enriquecidas introducidas en Python 2.2 que serán el estándar en Python 3.0 pero que aún conviven con las clases «clásicas» por razones de retrocompatibilidad. Además de las propiedades las clases de nuevo estilo añaden otras funcionalidades como descriptores o métodos estáticos.

Para que una clase sea de nuevo estilo es necesario, por ahora, que extienda una clase de nuevo-estilo. En el caso de que no sea necesario heredar el comportamiento o el estado de ninguna clase, como en nuestro ejemplo anterior, se puede heredar de object, que es un objeto vacio que sirve como base para todas las clases de nuevo estilo.

La diferencia principal entre las clases antiguas y las de nuevo estilo consiste en que a la hora de crear una nueva clase anteriormente no se definía realmente un nuevo tipo, sino que todos los objetos creados a partir de clases, fueran estas las clases que fueran, eran de tipo instance.

Métodos especiales

Ya vimos al principio del artículo el uso del método __init__. Existen otros métodos con significados especiales, cuyos nombres siempre comienzan y terminan con dos guiones bajos. A continuación se listan algunos especialmente útiles.

__init__(self, args)
Método llamado después de crear el objeto para realizar tareas de inicialización.

__new__(cls, args)
Método exclusivo de las clases de nuevo estilo que se ejecuta antes que __init__ y que se encarga de construir y devolver el objeto en sí. Es equivalente a los constructores de C++ o Java. Se trata de un método estático, es decir, que existe con independencia de las instancias de la clase: es un método de clase, no de objeto, y por lo tanto el primer parámetro no es self, sino la propia clase: cls.

__del__(self)
Método llamado cuando el objeto va a ser borrado. También llamado destructor, se utiliza para realizar tareas de limpieza.

__str__(self)
Método llamado para crear una cadena de texto que represente a nuestro objeto. Se utiliza cuando usamos print para mostrar nuestro objeto o cuando usamos la función str(obj) para crear una cadena a partir de nuestro objeto.

__cmp__(self, otro)
Método llamado cuando se utilizan los operadores de comparación para comprobar si nuestro objeto es menor, mayor o igual al objeto pasado como parámetro. Debe devolver un número negativo si nuestro objeto es menor, cero si son iguales, y un número positivo si nuestro objeto es mayor. Si este método no está definido y se intenta comparar el objeto mediante los operadores <, <=, > o >= se lanzará una excepción. Si se utilizan los operadores == o != para comprobar si dos objetos son iguales, se comprueba si son el mismo objeto (si tienen el mismo id).

__len__(self)
Método llamado para comprobar la longitud del objeto. Se utiliza, por ejemplo, cuando se llama a la función len(obj) sobre nuestro objeto. Como es de suponer, el método debe devolver el número la longitud del objeto.

Existen bastantes más métodos especiales, que permite entre otras cosas utilizar el mecanismo de slicing sobre nuestro objeto, utilizar los operadores aritméticos o usar la sintaxis de diccionarios, pero un estudio exhaustivo de todos los métodos queda fuera del propósito del artículo.

62 comentarios en «Python: Orientación a objetos»

  1. He estado viendo que has estado escribiendo varios tutoriales de Python. Actualmente yo me encuentro aprendiendo python, así como procesamiento de imagenes. He escrito un pequeño programa en python que poliedriza una esfera. Me pregunto si fuera posible que vieras mi código y me dijeras si esta bien escrito, o si debo darle otro enfoque. Yo creo que se puede mejorar mucho todavía. Actualmente mi código es funcional y hace lo que tiene que hacer, solo me interesa escribirlo de manera adecuada para hacerlo mas eficiente y escalable. El link es el siguiente: http://comunidadgeek.wordpress.com/2008/02/29/google-code/
    Saludos.
    Gracias.

  2. Buenas, yo veo otra forma de «simular» la sobrecarga de métodos:

    O sea, usar parametros por defecto:

    def funcion(parametro1 = «», parametro2 = «»)

    Aqui la puedes llamar sin parametros, con 1 parametro o con 2. O sea, si vas a tener 2 funciones con el mismo nombre, pones solo 1, y el parametro extra que pueda tener la otra, lo pones así y no será obligatorio.

    Por lo demás, está perfecto 🙂

    1. Pero dentro del codigo del metodo se tendrìa que discriminar que es lo que se tiene que realizar dependiendo de los paramteros y de los valores por defecto (con ifs) verdad? o estoy equivocado

      1. Hola Raul. Tremendo Libro. Es mi segunda biblia. Sabes esto de orientacion a objetos me trae con los pelos de punta. No pudieras por favor hacer y explicar un ejemplo pasando variables globales y parametros más complejos. Ando enrredado y en vez de solucionar problemas con buenas practicas, soluciono con malas practicas digo. (copiar y pegar una codigo de una funcion y crear dos variables en vez de pasar variables de una a la otra) Tengo un buen ejemplo de python turtle. Esta a la orden…

        1. Jaja es increíble lo que uno escribe cuando no sabe bien las cosas. Raúl de nuevo gracias por tan buen libro. Un año después del comentario y miles de líneas de código después soy instructor de python en la academia de software libre de mi localidad. Saludos desde Venezuela hermano

  3. simplemente esta exelente el contenido. si tan solo todas un 5% de los web site edificaran como este quisas el mundo cambiara de situacion. solo felicito a todos los que visiten este web site ya que atinaron al blanco.. me gusta saver que havemos personas muchas personas con gustos comunes. cuanquier cosa.. pueden contactarme a alfredoceballosp@gmail.com pueden escribirme amistosamente. sobre programacion lo que quieran estoy dado a aprender y ense;ar todo lo que se. y no sepa. gracias. a todos.

  4. Hola Raúl, muy bueno el resumen, tengo una duda, y es que no he comprendido lo de mi_coche=coche(3). Donde tengo que escribir eso? Me imagino que esa es la clave para correr despues el codigo desde el interprete. Un saludo y gracias

  5. Pingback: programacion de videojuegos con pygame « Python Mania

  6. Pingback: tutorial pygame 1: introducción a la programacion de videojuegos « Python Mania

  7. Pingback: Tutorial Pygame 3: creando un videojuego (el clasico pong) « Python Mania

  8. Graias por el artículo, hacía años que no tocaba clases y esto me ha ayudado a refrescar la POO al entrar en el lenguaje Python.

  9. Gracias por el articulo me sirvio de mucho, lo unico que cuando utiliso la sentencia if al poner else: me arroja un error de sintaxis

    SyntaxError: invalid syntax

    espero que alguien me pueda ayudar 😀

    gracias de antemano

  10. Hola, siguiendo tu ejemplo de la Programación Orientada a Objetos en Python, al escribir ‘mi_coche.conducir()’, el intérprete me devuelve solo la primera parte del print: ‘Quedan ‘, y despues me da un error que dice que ‘el nombre global gasolina no está definido’. Esto es lo unico que falla del código, lo demás (gasolina, arrancar, restar 1 a gasolina cada vez que se llama a conducir, incluso cuando no tiene gasolina me devuelve que no se mueve).
    El código que he escrito es el mismo que el del ejemplo, con la diferencia de que el mío no funciona en esto que he dicho.
    ¿Alguien podría echarme una mano? Gracias de antemano. 😉

    1. Si te fijas en la primera página de Python para todos verás que el autor es Raúl González Duque, que soy yo. Y si te fijas en la tercera página, verás que este es mi blog 😉

    2. Ese frió en tu pecho no es mas que tu dignidad escurriéndose entre el hueco cerebro que te llevo a hablar sin pensar,haz quedado como un culo

  11. Alguien me puede decir cuál es la diferencia entre estas dos clases:

    class nombre(object):
    foo

    class nombre():
    foo

    En algunos ejemplos los veo de una manera y en otros de otras.

    Yo lo he estado probando con ejemplo básico y por ejemplo lo que he notado es que cuando creo una clase sin parámetros y creo setters y getters con «property» no puedo usar en el código las funciones originales (getVar(self), setVar(self, var)) (no es realmente que no las pueda usar, no me da excepción pero no funciona bien). Por el contrario, cuando creo la clase con el parámetro object y creo setters y getters con «property» puedo usar las dos formas, la «encapsulada» (x = objeto.metodo) y a la vez la función original ( objeto.getVar()) (y por supuesto funciona como lo tiene que hacer).

    Para todos los que como yo habéis empezado con Python tras este magnífico manual os recomiendo una vez acabado con este y hacer las prácticas rutinarias proseguir con http://nomuerde.netmanagers.com.ar/indice.html

    Saludos 😉

  12. Muy buenas, fantastico libro y muy agradecido por el. Aunque tengo una duda que no consigo aclarar…

    LLevo algún tiempo aprendiendo C# y me resulta muy sencillo crear un objeto a partir de una clase:

    nombreClase nombreMiObjeto = new nombreClase()

    Sin embargo en python no me queda claro como invocar al constructor para que, de una clase de un archivo.py crear un objeto…

    En tu ejemplo se crea un objeto desde el interprete, pero..¿y en dos archivos diferentes en la misma carpeta? Gracias por tu esfuerzo de nuevo! un saludo.

  13. Hola, estoy tratando de hacer lo siguiente en Phyton y me marca este error

    Open a terminal command and follow these steps:
    C:\>cd C:\MapFish
    cuando le doy enter me aparece el siguiente error marcando de rojo los dos puntos
    SyntaxError: invalid syntax.

  14. Hola, tengo una duda. el Coche funciona en el IDLE, pero si guardo un archivo.py solo con el codigo del Coche (class Coche: def __init__ #etc..), el archivo no se puede ejecutar.. Entiendo que falta algo para que se pueda ejecutar, y quisiera saber Qué es???.. quisiera usar ese codigo para un programa interactivo. disculpen si la pregunta es tonta, estoy empezando a programar..

  15. disculpen por la pregunta esque soy renoov jaja que es instanciacion y que es inicializacion?
    ya me creia programador asta que llegue al tema de las clases… quizas tengo qeu profundizar mas en lo que es clases? que me aconsejan…

  16. hola ya estoy aprendiendo mas gracias a este tutorial…
    pero tengo una pregunta cual es el error en este codigo?

    while 1:
    class moto:
    def __init__(self, g=3):
    self.g = g
    def arrancar(self):
    if g > 0:
    print «arranca»
    else:
    print «no arranca»
    def avansar(self):
    if g > 0:
    print «te quedan», g, «litros»
    else:
    print «se acabo la gasolina»
    motito = moto(20)
    e = raw_input()
    if e == «a»:
    motito.arrancar()
    elif e == «c»:
    motito.avansar()
    else:
    print «preciona la opcion correcta»
    solo me funciona cuando se ejecuta el else
    en las demas me sale que g no esta definida no se porque, si se supone que g vale 20 verdad?

  17. Debo ser muy idiota, estoy tratando de instanciar un objeto «coche» con el ejemplo que se muestra arriba y no entiendo como se hace, tal y como esta en el ejemplo. Cuando trato de escribir exactamente eso mismo en el interprete interactivo de python, me da un error. Pense que este ejemplo era para principiantes que no conocen nada de Python todavia, pero parece que debo buscar algo mas basico todavia…

  18. Hola, buen día.

    Para los que entienden por códigos, les dejo un ejemplo de un «auto» que acabo de hacer, con avanzar, cargar bencina, km por litro, precio de la bencina, saldo:

    class auto:
    def __init__(self):

    self.dinero = 5
    self.precioxlitro = 2
    self.kmxlitro = 5
    self.gasolina = 0
    self.estado_encendido = False

    def encender(self, estado):
    if estado == 1:
    if self.gasolina > 0:
    self.estado_encendido = True
    return True
    else:
    self.estado_encendido = False
    return False
    else:
    self.estado_encendido = False
    def cuenta_x(self):

    return «Tu saldo es:%s»%self.dinero

    def cargar_gasolina(self, litros):
    self.litros = litros
    self.cuenta = self.litros*self.precioxlitro
    self.dinero = self.dinero-self.cuenta
    if self.dinero > 0:
    self.gasolina = a.litros
    self.km_disponibles = self.gasolina*self.kmxlitro
    return True
    else:
    return False
    def avanzar(self, cuadras):
    if self.estado_encendido:
    if cuadras «)
    if a.avanzar(av):
    print «Tienes», a.km_disponibles, «KM para recorrer»
    a.km_disponibles -= av
    print «Vamos a avanzar», av, «km»
    print «Te quedan %sKM»%a.km_disponibles, «ahora»
    else:
    print «No te alcanzan los KM o prende el carro!»
    else:
    print «El auto no se ha encendido…»
    else:
    print «No te alcanza el $»

  19. Tengo una pregunta, para esto lo voy a poner en un código facil; tengo la clase manzana

    class Manzana:
    def __init__(self,volumen):
    self.volumen = volumen
    print («el volumen es «, self.volumen, «cm^3»)

    Ahora Creo algunos objetos manzana, digamos

    manzana1 = Manzana(10)
    manzana2 = Manzana(9)
    manzana3 = Manzana(11)

    Finalmente y es la duda, quiero crear un metodo para que me calcule el promedio de las manzanas, pero que si yo agrego otra manzana, con el mismo método me vuelva a calcular el promedio de las cuatro y así sucesivamente para no tenerlo que hacer desde cero cada vez que quiera sacar un promedio. (es decir la duda es cómo accedo a un atributo específico de cada objeto pero automáticamente, que no tenga que escribir manzana1.volumen+manzana2.volumen…)
    (Les agradecería ya que lo necesito para algo mucho más serio de ingeniería eléctrica pero es el mismo principio)

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.