├── material.ipynb └── README.md /material.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "class Point:\n", 10 | " pass" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 3, 16 | "metadata": {}, 17 | "outputs": [ 18 | { 19 | "name": "stdout", 20 | "output_type": "stream", 21 | "text": [ 22 | "<__main__.Point object at 0x7fa620609460>\n" 23 | ] 24 | } 25 | ], 26 | "source": [ 27 | "point = Point()\n", 28 | "print(point)" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 9, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "class Point:\n", 38 | " x: int\n", 39 | " y: int" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 14, 45 | "metadata": {}, 46 | "outputs": [ 47 | { 48 | "name": "stdout", 49 | "output_type": "stream", 50 | "text": [ 51 | "Entidad geometrica abstracta que representa una ubicación en un espacio.\n" 52 | ] 53 | } 54 | ], 55 | "source": [ 56 | "class Point:\n", 57 | " definition: str = \"Entidad geometrica abstracta que representa una ubicación en un espacio.\"\n", 58 | "\n", 59 | "point = Point()\n", 60 | "print(point.definition)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 18, 66 | "metadata": {}, 67 | "outputs": [ 68 | { 69 | "name": "stdout", 70 | "output_type": "stream", 71 | "text": [ 72 | "Entidad geometrica abstracta que representa una ubicación en un espacio. 1 1\n", 73 | "2 2\n", 74 | "0 0\n" 75 | ] 76 | } 77 | ], 78 | "source": [ 79 | "class Point:\n", 80 | " definition: str = \"Entidad geometrica abstracta que representa una ubicación en un espacio.\"\n", 81 | " def __init__(self, x=0, y=0):\n", 82 | " self.x = x\n", 83 | " self.y = y\n", 84 | " def move(self, new_x, new_y):\n", 85 | " self.x = new_x\n", 86 | " self.y = new_y\n", 87 | " def reset(self):\n", 88 | " self.x = 0\n", 89 | " self.y = 0\n", 90 | "\n", 91 | "\n", 92 | "point = Point(x=1, y=1)\n", 93 | "print(point.definition, point.x, point.y)\n", 94 | "point.move(new_x=2, new_y=2)\n", 95 | "print(point.x, point.y)\n", 96 | "point.reset()\n", 97 | "print(point.x, point.y)" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 3, 103 | "metadata": {}, 104 | "outputs": [ 105 | { 106 | "name": "stdout", 107 | "output_type": "stream", 108 | "text": [ 109 | "1.4142135623730951\n" 110 | ] 111 | } 112 | ], 113 | "source": [ 114 | "class Point:\n", 115 | " definition: str = \"Entidad geometrica abstracta que representa una ubicación en un espacio.\"\n", 116 | " def __init__(self, x: float=0, y: float=0):\n", 117 | " self.x = x\n", 118 | " self.y = y\n", 119 | " def move(self, new_x: float, new_y: float):\n", 120 | " self.x = new_x\n", 121 | " self.y = new_y\n", 122 | " def reset(self):\n", 123 | " self.x = 0\n", 124 | " self.y = 0\n", 125 | " def compute_distance(self, point)-> float:\n", 126 | " distance = ((self.x - point.x)**2+(self.y - point.y)**2)**(0.5)\n", 127 | " return distance\n", 128 | "\n", 129 | "first_point = Point(x=1, y=1)\n", 130 | "second_point = Point(x=2, y=2)\n", 131 | "# should be root of 2 (?)\n", 132 | "print(first_point.compute_distance(second_point))" 133 | ] 134 | } 135 | ], 136 | "metadata": { 137 | "kernelspec": { 138 | "display_name": "Python 3", 139 | "language": "python", 140 | "name": "python3" 141 | }, 142 | "language_info": { 143 | "codemirror_mode": { 144 | "name": "ipython", 145 | "version": 3 146 | }, 147 | "file_extension": ".py", 148 | "mimetype": "text/x-python", 149 | "name": "python", 150 | "nbconvert_exporter": "python", 151 | "pygments_lexer": "ipython3", 152 | "version": "3.8.10" 153 | } 154 | }, 155 | "nbformat": 4, 156 | "nbformat_minor": 2 157 | } 158 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Programación Orientada a Objetos - UNAL 2 | 3 | ## Tabla de Contenidos 4 | - [Clase 6: Clases y Objetos](#clase-6-clases-y-objetos) 5 | - [Objetos](#objetos) 6 | - [Clases en Python](#clases-en-python) 7 | - [Atributos](#atributos) 8 | - [Atributos de clase](#atributos-de-clase) 9 | - [Atributos de instancia](#atributos-de-instancia) 10 | - [Inicialización y Self](#inicializacion-__init__-y-el-si-mismo-self) 11 | - [¿Por qué es necesario self?](#por-qué-es-necesario-self) 12 | - [¿Cómo funciona self?](#cómo-funciona-self) 13 | - [Métodos](#métodos) 14 | - [Objetos como argumentos](#objetos-como-argumentos) 15 | - [Ejercicios](#ejercicio) 16 | 17 | ---- 18 | ## Clase 6: Clases y Objetos 19 | 20 | ### Objetos 21 | En Python, todo es un objeto, incluidos los datos de tipos primitivos y las estructuras de datos. Un objeto **es una instancia de una clase**, que a su vez es una plantilla para crear objetos (*binded definitions*). Los objetos pueden contener tanto datos (**atributos**) como código (**métodos**). 22 | 23 | Pero entonces...¿qué es "instanciar"?... 24 | 25 | En el contexto de la programación orientada a objetos en Python, "instanciar" un objeto es el proceso mediante el cual se crea un objeto único a partir de una clase. Una clase puede considerarse como un **plano** o un *template* que define los atributos y métodos que sus objetos (instancias) tendrán. Cuando `instanciamos` un objeto, estamos creando una entidad concreta en la memoria que sigue las especificaciones de su clase respectiva. 26 | 27 | Una instancia es, por lo tanto, **un objeto específico creado a partir de una clase**. Cada instancia tiene sus propios atributos (o incluso métodos si se pasan distintos argumentos), que pueden tener diferentes valores que distinguen una instancia de otra. 28 | 29 | **Importante:** A pesar de que múltiples instancias de una misma clase pueden compartir la misma estructura (es decir, los mismos atributos y métodos), los valores de esos atributos pueden variar entre instancias. 30 | 31 | Y todo esto para? 32 |
33 | Spoilers 34 |

35 | La instanciación es fundamental en la programación orientada a objetos porque permite a los desarrolladores crear múltiples objetos únicos a partir de una sola definición de clase. Esto facilita la reutilización de código y la organización del programa, permitiendo que los objetos interactúen entre sí. Cada objeto puede contener sus propios datos, lo que permite representar entidades del mundo real dentro del código de manera aislada y modular. 36 |

37 |
38 | 39 | ## Clases en Python 40 | Una clase se define con la palabra clave `class` seguida de un nombre y dos puntos. La clase más simple en Python no necesita nada más que la palabra clave pass para representar un bloque de código vacío. 41 | 42 | **Pro tip:** El nombre de las clases debe ir en `CamelCase`, con la primera palabra capitalizada. 43 | 44 | ```python 45 | class MyFirstClass: 46 | pass 47 | ``` 48 | 49 | ```python 50 | class Point: 51 | pass 52 | ``` 53 | 54 | **Dato:** `pass` permite definir un bloque de código sin funcionalidad, sin tener el error de que se tiene un bloque no definido. 55 | 56 | 57 | **Ejercicio:** Probar esto y ver qué pasa... 58 | 59 | ```python 60 | class Point: 61 | pass 62 | 63 | point = Point() 64 | print(point) 65 | ``` 66 | 67 | ### Atributos 68 | En Python, los atributos de una clase son variables asociadas a esta, que definen las **características** de los objetos que se crean a partir de ella. 69 | 70 | #### Atributos de clase 71 | Son variables asociadas a la clase misma, no a las instancias de la clase. Estos atributos son compartidos por todas las instancias de la clase. Se definen directamente en el cuerpo de la clase, fuera de cualquier método. 72 | 73 | ```mermaid 74 | classDiagram 75 | class Point { 76 | +str definition 77 | } 78 | ``` 79 | 80 | ```python 81 | class Point: 82 | definition: str = "Entidad geometrica abstracta que representa una ubicación en un espacio." 83 | 84 | point = Point() 85 | print(point.definition) 86 | ``` 87 | 88 | #### Atributos de instancia 89 | Son variables específicas de cada instancia de una clase. Cada objeto creado a partir de la clase puede tener valores diferentes para estos atributos. Se definen comúnmente dentro del método `__init__`, utilizando el prefijo `self` para indicar que son atributos de instancia. 90 | 91 | ```python 92 | class Point: 93 | definition: str = "Entidad geometrica abstracta que representa una ubicación en un espacio." 94 | def __init__(self, x=0, y=0): 95 | self.x = x 96 | self.y = y 97 | 98 | point = Point() 99 | print(point.definition, point.x, point.y) 100 | ``` 101 | 102 | ```mermaid 103 | classDiagram 104 | class Point { 105 | +str definition 106 | +int x 107 | +int y 108 | +__init__(x, y) 109 | } 110 | ``` 111 | 112 | ### Inicializacion (`__init__`) y el si mismo (`self`) 113 | 114 | Instanciar un objeto implica llamar a la clase como si fuera una función, lo que a menudo involucra pasar valores iniciales a su método constructor `__init__`. Este método constructor **inicializa** los nuevos objetos, realizando la configuración inicial, de atributos y métodos. 115 | 116 | - `__init__` es el método de inicialización de un objeto recién creado. Se utiliza para inicializar los atributos del objeto, es decir, para darles un estado inicial. 117 | - No devuelve un valor; su propósito es inicializar la instancia: `def __init__(self)->None:`. 118 | - Se denomina *dunder* init, porque double underscore, so doble __, pretty neat. 119 | 120 | En Python, `self` es un término que se utiliza para referirse a la instancia actual de la clase. En otras palabras, `self` representa al objeto específico que está ejecutando. Este término no es una palabra reservada de Python pero es una convención fuertemente arraigada (como todo en Python). 121 | 122 | Cuando se define un método en una clase, el primer argumento del método se refiere a la instancia en la que el método está siendo llamado. Por convención, este primer argumento es `self`. Esto permite acceder a los atributos y métodos del objeto desde dentro de la clase. 123 | 124 | Algunos se preguntarán....y esto qué...pues es magia pura, porque después del inicializador se puede compartir todo el objeto con el resto de la clase...y si aún no le ven utilidad, si esto no existiera, para cada método dentro de la clase, habría que estar pasando variables (que representan atributos) a través de argumentos a todos los métodos de la clase, lo cual es super largo y engorroso. La magia del `self`, es esa, proveer autoconciencia, saber qué soy, qué tengo, y qué puedo hacer en cada momento....es **M A G I A**. 125 | 126 | **Disclaimer:** En concepto de `self` sería más o menos el equivalente de `this` en Java. 127 | 128 | #### ¿Por qué es necesario `self`? 129 | `self` es necesario para diferenciar entre atributos y métodos de la instancia y variables locales o globales. Permite a un objeto referenciar sus propios atributos y métodos dentro de la clase. Sin `self`, no tendríamos una forma de acceder a estos datos desde dentro de los métodos de la clase. 130 | 131 | #### ¿Cómo funciona `self`? 132 | - Cuando se crea una instancia de una clase, Python automáticamente pasa la instancia recién creada al método `__init__` como el primer argumento. Este argumento se recibe en el parámetro `self`. 133 | - Para cualquier método de instancia, el objeto sobre el cual se llama el método se pasa automáticamente como el primer argumento, y se recibe en `self`. 134 | 135 | ### Métodos 136 | Una clase no solo tiene atributos (características) sino también métodos (comportamientos/acciones), estos métodos se definen como funciones dentro de la estructura de la clase. Ya se vió el primer método importante, el inicializador, existen unos cuantos más, pero de momento cualquier funcionalidad que se le quiera atribuir a la clase, es tan simple como agregar más métodos en su interior. 137 | 138 | ```mermaid 139 | classDiagram 140 | class Point { 141 | +str definition 142 | +int x 143 | +int y 144 | +__init__(x, y) 145 | +reset() 146 | +move() 147 | } 148 | ``` 149 | 150 | 151 | ```python 152 | class Point: 153 | definition: str = "Entidad geometrica abstracta que representa una ubicación en un espacio." 154 | def __init__(self, x=0, y=0): 155 | self.x = x 156 | self.y = y 157 | def move(self, new_x, new_y): 158 | self.x = new_x 159 | self.y = new_y 160 | def reset(self): 161 | self.x = 0 162 | self.y = 0 163 | 164 | point = Point(x=1, y=1) 165 | print(point.definition, point.x, point.y) 166 | point.move(new_x=2, new_y=2) 167 | print(point.x, point.y) 168 | point.reset() 169 | print(point.x, point.y) 170 | ``` 171 | 172 | #### Objetos como argumentos... 173 | Como se vio todo en Python son objetos, de manera que los métodos de una clase y la clase en sí pueden recibir argumentos tipo objeto. 174 | 175 | ```mermaid 176 | classDiagram 177 | class Point { 178 | +str definition 179 | +int x 180 | +int y 181 | +__init__(x, y) 182 | +reset() 183 | +move(x, y) 184 | +compute_distance(point) 185 | } 186 | ``` 187 | 188 | ```python 189 | class Point: 190 | definition: str = "Entidad geometrica abstracta que representa una ubicación en un espacio." 191 | def __init__(self, x: float=0, y: float=0): 192 | self.x = x 193 | self.y = y 194 | def move(self, new_x: float, new_y: float): 195 | self.x = new_x 196 | self.y = new_y 197 | def reset(self): 198 | self.x = 0 199 | self.y = 0 200 | def compute_distance(self, point: "Point")-> float: 201 | distance = ((self.x - point.x)**2+(self.y - point.y)**2)**(0.5) 202 | return distance 203 | 204 | first_point = Point(x=1, y=1) 205 | second_point = Point(x=2, y=2) 206 | # should be root of 2 (?) 207 | print(first_point.compute_distance(second_point)) 208 | ``` 209 | 210 | **Ejercicio:** 211 | Defina una clase siguiendo la siguiente estructura: 212 | ```mermaid 213 | classDiagram 214 | class Person { 215 | +str specie 216 | +int age 217 | +str name 218 | +greet() 219 | +is_older_than(Person) 220 | } 221 | ``` 222 | - *specie*: Class attribute 223 | - *age*, *name*: Instance attributes 224 | - greet(): should print-> , is gretting you! 225 | - is_older_than(Person)->bool: Dtermine if the instance person is older than the argument person. 226 | 227 | ---- 228 | 229 | ### Info adicional 230 | - [Clases - ref de Python](https://docs.python.org/3/tutorial/classes.html) 231 | - [Clases y objetos en Python](https://realpython.com/python3-object-oriented-programming/) 232 | - [POO principles in Python - Super Post](https://medium.com/@aserdargun/advanced-oop-in-python-a5f6130da291) 233 | - [POO with spiderman memes](https://medium.com/@bdov_/https-medium-com-bdov-python-this-is-an-object-that-is-an-object-everything-is-an-object-fff50429cd4b) 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | --------------------------------------------------------------------------------