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.

Comentarios
  1. Gracias por el aporte! es de mucha ayuda para aprender… espero que sigas enseñando.

    Responder

  2. 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.

    Responder

  3. Kartoffel

    También quedan muy chulos los métodos __getitem__ y su compañero __setitem__

    Responder

  4. Excelente la review y el paso a paso que estan mostrando de este magnífico lenguaje de Programación. Sigan asi!!!

    Responder

  5. Te lo has currao…
    buen trabajo. Saludos.

    Responder

  6. Once again, mil gracias!!!

    Responder

  7. Fox

    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 🙂

    Responder

    • 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

      Responder

  8. Cierto, con valores por defecto para los parámetros también se puede hacer, claro.

    Edito 🙂

    Responder

  9. kendal

    Que tal copia del libro “python para todos”, seria bueno que hagas tus propios modelos para explicar la POO. <,<

    Responder

    • @kendal no se si te he interpretado muy bien, pero creo haber entendido que me estás acusando de plagiar “Python para todos”…

      Si te fijas en las primeras páginas del libro y miras el autor (Raúl González Duque) y la web del libro (http://mundogeek.net/tutorial-python/) verás que yo soy el autor 😛

      Responder

      • Jorge

        jajaja Dios santo…
        Excelente articulo, me vino muy bien.
        Gracias y felicitaciones.

        Responder

      • 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…

        Responder

        • víctor

          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

          Responder

  10. Anónimo

    Muy bueno Raúl 😉

    Responder

  11. Cuanta curiosidad y amor por python, como debe ser, jaja… gracias por estos pedazo de tutoriales que nos das siempre

    Responder

  12. Manuel

    Muchas gracias!! Justamente tienes la info que necesitaba!

    Saludos.

    Responder

  13. alfredo

    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.

    Responder

  14. Muchas gracias, esto resuelve algunas dudas eternas que doy por sentadas y por no googlear las uso con fe xD

    Responder

  15. Siegfried

    mmm…

    si, si esta bueno el material que exponesn…

    SALUDOS!!!

    Responder

  16. gracias, resuelve algunas de mis dudas al manejar objetos.

    Responder

  17. tools

    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

    Responder

  18. […] Conocimiento básico de python, por lo menos como se definen funciones y clases […]

    Responder

  19. […] Conocimiento básico de python, por lo menos como se definen funciones y clases […]

    Responder

  20. […] luego en el def __init__(self): se define que se hará cuando se llama al instanciar la clase. (una explicación mas completa por aquí). En nuestro caso se le dice primero que inicie pygame.sprite.Sprite (algo un poco raro pero […]

    Responder

  21. N6

    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.

    Responder

  22. 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

    Responder

  23. Gracias 😀

    Responder

  24. 4N0N1M0U5

    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. 😉

    Responder

  25. Carlos González

    Estimado, muchas gracias. Una guía rápida muy precisa y útil.

    Saludos!

    Responder

  26. Cesar Antonio

    muchas gracias muy buena pagina…seria muy bueno tambien que pusieran un ejemplo en tkinter…gracias

    Responder

  27. gasper

    Muy buen esta guia para empezar.. pero si quieren profundizar aun mas les recomiendo Dive into Python…

    Responder

  28. hfy

    Responder

  29. jorge

    como puede utilizar el metodo _del_ para eliminar un objeto dentro de una lista de objetos??

    Responder

  30. Anónimo

    “python para todos” vean ese manual. no es copia como este

    Responder

    • 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 😉

      Responder

  31. 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 😉

    Responder

  32. oliver_sebas

    Hola alguien que me pueda ayudar con un programa no se que hacer 🙁 lo agradeceria dejo mi correo osebastian.527@gmail.com

    Responder

  33. juan

    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.

    Responder

  34. Israel

    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.

    Responder

    • víctor

      eso no es python. eso es cmd

      Responder

      • geomorillo

        LOL No es python estas en lo correcto pero tampoco cmd, especificamente es un comando la linea de comandos de dos.

        Responder

  35. 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..

    Responder

  36. Rodi

    QUE BUEEEEEEEEEEEEEEEEEEEEEEEEEEN POST DE VERDAD EXCELENTE NO PUEDE ESTAR MEJOR EXPLICADO!

    Responder

  37. jose

    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…

    Responder

  38. Esteban

    Excelente aporte, muy bien explicado y fácil de seguir e implementar. Gracias!

    Responder

  39. jose

    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?

    Responder

  40. luis

    gracias, muy educativo. me ha servido de ayuda.

    Responder

  41. wwweedd

    Como se ejecuta el de cocodrilo?que hay que poner dentro de lo sparentesis?

    Responder

  42. Me encantan tus posts. Llegué aquí por tu libro que lo uso de referencia para enseñarle a otras personas.
    Realmente muchas gracias por todo 🙂
    Paz!

    Responder

  43. Frank

    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…

    Responder

  44. Ruben

    Que buenos datos de poo, pasa me la voz si tienes un canal en YOUTUBE y si no tienes crea te uno!

    Responder

  45. SamCas

    Hola, gracias por el aporte. No he entendido esto de los objetos en Python hasta leer tu artículo.

    Responder

  46. Germán

    Gracias por el aporte.

    Responder

  47. 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 $”

    Responder

  48. Muchas gracias por esta página, es simplemente excelente! 😀

    Responder

  49. Andrés Estepa

    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)

    Responder

  50. Edgar Oliva

    MUY BUEN RESUMEN
    GRACIIAS!!!

    Responder

Deja un comentario