{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "view-in-github", "colab_type": "text" }, "source": [ "\"Open" ] }, { "cell_type": "markdown", "metadata": { "id": "P-nmPiBSpxjM" }, "source": [ "# El Constructor" ] }, { "cell_type": "markdown", "metadata": { "id": "Ow1TKJjPpxjS" }, "source": [ "## Repasemos\n", "Recordemos que ya hemos creado la clase Coche con cuatro propiedades y dos métodos." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "id": "wys4kaQApxjV", "outputId": "04689409-a69f-4e89-ba8e-cf01343f347b", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Arrancando...\n", "ruedas: 4\n", "ancho: 181\n", "largo: 426\n", "¿en marcha?: True\n" ] } ], "source": [ "class Coche():\n", " largo = 426 # atributo de clase\n", " ancho = 181\n", " ruedas = 4\n", " enmarcha = False\n", "\n", " def arrancar(self):\n", " print(\"Arrancando...\")\n", " self.enmarcha=True\n", "\n", " def estado(self):\n", " if self.enmarcha:\n", " return \"El coche está en marcha\"\n", " else:\n", " return \"El coche está parado\"\n", "\n", "miCoche = Coche() # instanciación del primer objeto, así creamos el objeto miCoche\n", "\n", "miCoche.arrancar() # accedemos al método arrancar\n", "miCoche.estado() # accedemos al método estado\n", "\n", "print(\"ruedas: \", miCoche.ruedas) # accedemos a la propiedad ruedas\n", "print(\"ancho: \", miCoche.ancho) # accedemos a la propiedad ancho\n", "print(\"largo: \", miCoche.largo) # accedemos a la propiedad largo\n", "print(\"¿en marcha?: \", miCoche.enmarcha) # accedemos a la propiedad enmarcha" ] }, { "cell_type": "markdown", "metadata": { "id": "ruEJRKwbpxja" }, "source": [ "## Creamos un segundo objeto\n", "Crearemos un segundo objeto de la clase Coche que necesariamente ha de tener distinto nombre." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "id": "iGslUTympxjb", "outputId": "6d152707-4514-4f18-918f-5082167f3d26", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "ruedas: 4\n", "ancho: 181\n", "largo: 426\n", "¿en marcha?: False\n" ] } ], "source": [ "tuCoche = Coche() # instanciación del segundo objeto, así creamos el objeto tuCoche\n", "tuCoche.estado() # accedemos al método estado que indicará 'parado'\n", " # ya que aún no hemos arrancado\n", "print(\"ruedas: \", tuCoche.ruedas) # accedemos a la propiedad ruedas\n", "print(\"ancho: \", tuCoche.ancho) # accedemos a la propiedad ancho\n", "print(\"largo: \", tuCoche.largo) # accedemos a la propiedad largo\n", "print(\"¿en marcha?: \", tuCoche.enmarcha) # accedemos a la propiedad enmarcha" ] }, { "cell_type": "markdown", "metadata": { "id": "1Mdi6iBCpxjc" }, "source": [ "Los dos objetos miCoche y tuCoche comparte algunas propiedades (largo, ancho, ruedas) pero en otras difieren (enmarcha). \n", "El primer coche está en marcha, porque se arrancó, y el segundo no." ] }, { "cell_type": "markdown", "metadata": { "id": "yOu0hQfFpxje" }, "source": [ "## Añadiendo parámetros a un método\n", "Sería buena idea que el método 'arrancar' se encargara también de informar sobre el estado del coche, diciendo si está arrancado o no. Por ello, el método 'arrancar' absorberá al método 'estado', que dejará de existir. \n", "\n", "Vamos a añadir lo que hace el método 'estado' al método 'arrancar', para ello añadiremos el parámetro 'arrancamos'. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "id": "XSb26HYapxjf", "outputId": "16dd2103-aeeb-4e48-990e-75cfaca8e51a", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "El coche tiene 4 ruedas, un ancho de 181 y un largo de 426.\n", "El coche está en marcha\n" ] } ], "source": [ "class Coche():\n", " largo = 426\n", " ancho = 181\n", " ruedas = 4\n", " enmarcha = False\n", "\n", " def arrancar(self, arrancamos):\n", " self.enmarcha = arrancamos # La variable enmarcha será True o False según lo que nos pasen por el parámetro arrancamos\n", " if self.enmarcha:\n", " return \"El coche está en marcha\"\n", " else:\n", " return \"El coche está parado\"\n", "\n", " def estado(self):\n", " print(f\"El coche tiene {self.ruedas} ruedas, un ancho de {self.ancho} y un largo de {self.largo}.\")\n", "\n", "miCoche = Coche()\n", "miCoche.estado()\n", "print(miCoche.arrancar(True)) # ahora el método arrancar necesita obligatoriamente un argumento" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "id": "pECQolekpxjh", "outputId": "3735a40f-8531-4f15-e48a-26d06f0ec874", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "El coche está parado\n" ] } ], "source": [ "tuCoche = Coche()\n", "print(tuCoche.arrancar(False)) # para el objeto 'tuCoche' le pasamos como argumento False" ] }, { "cell_type": "markdown", "metadata": { "id": "Z4H6Q4SLpxjj" }, "source": [ "En la línea anterior hemos llamado al método arrancar. \n", "tuCoche.arrancar(False)\n", "\n", "El método arrancar vemos que tiene dos parámetros:\n", "- self: el objeto tuCoche se pasa al parámetro self\n", "- arrancamos: se le pasa False" ] }, { "cell_type": "markdown", "metadata": { "id": "XvEaAXZipxjk" }, "source": [ "#### Métodos con print y sin print" ] }, { "cell_type": "markdown", "metadata": { "id": "jKU6raRwpxjl" }, "source": [ "Hemos puesto un print en:\n", "- print(miCoche.arrancar(True))\n", "\n", "Pero no hemos puesto un print en:\n", "- miCoche.estado()\n", "\n", "Ambos son métodos aplicados sobre el mismo objeto. El motivo es que el método estado ya lleva un print en su definición y por el contrario el método arrancar no lleva ningún print en su definición y si se ejecuta sin poner un print no llegaríamos a ver lo que se retorna (al ejecutar en un archivo .py)." ] }, { "cell_type": "markdown", "metadata": { "id": "SHkvHZ1tpxjm" }, "source": [ "## El estado inicial\n", "Es habitual que las características comunes de los objetos que se se creen y que pertenezcan a una clase formen parte del denominado 'estado inicial' de esa clase. \n", "Esto supone que en el momento en el que se instancia un objeto concreto perteneciente a una clase ya se le aplica ese estado inicial con todas sus propiedades que consideremos interesantes que sean comunes.\n", "\n", "El estado inicial se define con un **constructor**." ] }, { "cell_type": "markdown", "metadata": { "id": "7m5h_RcBpxjn" }, "source": [ "## El método constructor\n", "Es un método inicial que proporciona el estado inicial de los objetos creados. \n", "Es una forma de especificar claramente cuál será el estado inicial de los objetos que pertenezcan a esa clase. \n", "Por convenio el constructor va arriba al crear la clase. \n", "\n", "Para crear un método constructor meteremos todas las propiedades comunes dentro de una estructura en forma de función con esta sintaxis: \n", "\n", "**`def __init__(self):`**\n", "\n", "Python llama automáticamente al método constructor cuando se crea una instancia. \n", "El método constructor contiene los atributos que deseamos tenga un objeto cuando se inicializa, lo que permite construir objetos con propiedades predefinidas.\n", "\n", "El parámetro ```self``` es obligatorio, hace referencia al propio objeto. Por costumbre se llama self en Python pero el nombre puede ser otro. En JAVA y en JS se llama *this*." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "id": "H2tog_hwpxjo", "outputId": "cd952262-d018-4b44-984b-47be6aac72c2", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "El coche está en marcha\n", "El coche tiene 4 ruedas, un ancho de 181 y un largo de 426.\n" ] } ], "source": [ "class Coche():\n", " def __init__(self): # aquí se crea el constructor. El método __init__ es llamado al crear el objeto\n", " self.largo = 426 # las propiedades llevan un self. que las antecede\n", " self.ancho = 181 # todas las variables que se crean en el constructor son\n", " self.ruedas = 4 # los atributos de clase y son comunes a todos los objetos\n", " self.enmarcha = False # que se crean de esta clase\n", "\n", " def arrancar(self, arrancamos):\n", " self.enmarcha = arrancamos\n", " if self.enmarcha:\n", " return \"El coche está en marcha\"\n", " else:\n", " return \"El coche está parado\"\n", "\n", " def estado(self):\n", " print(f\"El coche tiene {self.ruedas} ruedas, un ancho de {self.ancho} y un largo de {self.largo}.\")\n", "\n", "miCoche = Coche() # Al instanciar un objeto, aunque no se pasen atributos implícitamente, va self\n", "print(miCoche.arrancar(True))\n", "miCoche.estado()" ] }, { "cell_type": "markdown", "metadata": { "id": "VrXI1ONupxjp" }, "source": [ "Vemos que el código anterior funciona igual que sin la creación del constructor en este ejemplo sencillo, pero ahora tenemos la ventaja de tener todas las propiedades, con las que se inicia un objeto por defecto, agrupadas al inicio.\n", "\n", "El parámetro **self** debe ir puesto el primero en el método constructor y en todos los demás métodos, ya que hace referencia al propio objeto y es lo que espera encontrar el intérprete de Python.\n", "\n", "Al instanciar un objeto automáticamente se llama al método constructor y se aplican a ese objeto todos los atributos de clase, que son comunes para todos los objetos de esa clase." ] }, { "cell_type": "markdown", "metadata": { "id": "oLk0EInOpxjq" }, "source": [ "## Alterando propiedades\n", "Modificando atributos.\n", "\n", "Vamos a cambiar alguna de las propiedades de un objeto después de haber sido creado. \n", "Cuando el objeto se instancia (se crea) toma las propiedades que le da el constructor, pero luego podemos cambiarlas." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "id": "TRA57rropxjr", "outputId": "4ae58c8a-ea82-4f35-fb39-8e43513622c0", "colab": { "base_uri": "https://localhost:8080/" } }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "El coche tiene 6 ruedas, un ancho de 181 y un largo de 426.\n" ] } ], "source": [ "miCoche.ruedas += 2\n", "miCoche.estado()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.11" }, "colab": { "name": "calisto2_0030.ipynb", "provenance": [], "include_colab_link": true } }, "nbformat": 4, "nbformat_minor": 0 }