martes, 9 de octubre de 2018

Unidad No.3: Tarea #2: Clases y objetos en python

Un Programa Orientado a Objetos (POO) se basa en una agrupación de objetos de distintas clases que interactúan entre sí y que, en conjunto, consiguen que un programa cumpla su propósito.
En este paradigma de programación se intenta emular el funcionamiento de los objetos que nos rodean en la vida real. En Python cualquier elemento del lenguaje pertenece a una clase y todas las clases tienen el mismo rango y se utilizan del mismo modo.

Clases, atríbutos y métodos

Las clases en este contexto permiten definir los atributos y el comportamiento, mediante métodos, de los objetos de un programa. Una clase es una especie de plantilla o prototipo que se utiliza para crear instancias individuales del mismo tipo de objeto.

Los atributos definen las características propias del objeto y modifican su estado. Son datos asociados a las clases y a los objetos creados a partir de ellas.

De ello, se deducen los dos tipos de atributos o de variables existentes: variables de clase y variables de instancia (objetos).

Los métodos son bloques de código (o funciones) de una clase que se utilizan para definir el comportamiento de los objetos.

Tanto para acceder a los atributos como para llamar a los métodos se utiliza el método denominado de notación de punto que se basa en escribir el nombre del objeto o de la clase seguido de un punto y el nombre del atributo o del método con los argumentos que procedan: clase.atributo, objeto.atributo, objeto.método([argumentos]).

Un ejemplo característico de objeto Python donde se identifican fácilmente los métodos son las listas. Una lista es un objeto que permite contener una colección o secuencia de datos. Los datos de una lista deben ir separados por comas (,) y todo el conjunto entre corchetes. Una lista es una estructura mutable porque no sólo se puede acceder a los datos, además, es posible agregar nuevos elementos o suprimir aquellos que no sean necesarios. La clase lista (List) incorpora varios métodos para facilitar este trabajo:

# coding=utf-8
lista = ['c', 'a', 'b'] # Declara lista con tres elementos
lista.append('d') # Agrega elemento al final de lista con append()
lista.pop() # Borra último elemento de lista con método pop()
lista.sort() # Ordena la lista con el método sort()
print(lista) # ['a', 'b', 'c']


Variables de Clases y Variables de Instancias

En lenguajes que crean objetos a partir de clases, un objeto es una instancia de una clase. Y de una misma clase se pueden mantener activas en un programa más de una instancia al mismo tiempo.

Una variable de clase es compartida por todas las instancias de una clase. Se definen dentro de la clase (después del encabezado de la clase) pero nunca dentro de un método. Este tipo de variables no se utilizan con tanta frecuencia como las variables de instancia.

Una variable de instancia se define dentro de un método y pertenece a un objeto determinado de la clase instanciada.



Crear clases

Una clase consta de dos partes: un encabezado que comienza con el término class seguido del nombre de la clase (en singular) y dos puntos (:) y un cuerpo donde se declaran los atributos y los métodos:

class NombreClase:
'Texto para documentar la clase (opcional)'
varclase1 = "variable de clase1"
def nombremetodo1(self, var1):
self.var1 = var1
def nombremetodo2(self):
self.var1 += 1

La documentación de una clase debe situarse después del encabezado y justo antes del lugar donde se declaren las variables y los métodos de la clase.

Desde cualquier lugar de un programa se puede acceder a la cadena de documentación de una clase accediendo al atributo especial: NombreClase.__doc__ 

Todo lo que se incluye en una clase es opcional. De hecho, la clase más elemental aunque no tenga mucha utilidad puede estar vacía:

class Clase:
pass

La declaración pass indica que no se ejecutará ningún código. Sin embargo, esta clase una vez definida permite que se instancien objetos de ella e incluso es posible realizar algunas operaciones elementales.

En el siguiente ejemplo se define una clase mucho más completa:

class Alumno:
    'Clase para alumnos'
    numalumnos = 0
    sumanotas = 0

    def __init__(self, nombre, nota):
        self.nombre = nombre
        self.nota = nota
        Alumno.numalumnos += 1
        Alumno.sumanotas += nota

    def mostrarNombreNota(self):
        return(self.nombre, self.nota)

    def mostrarNumAlumnos(self):
        return(Alumno.numalumnos)

    def mostrarSumaNotas(self):
        return(Alumno.sumanotas)

    def mostrarNotaMedia(self):
        if Alumno.numalumnos > 0:
            return(Alumno.sumanotas/Alumno.numalumnos)
        else:
            return("Sin alumnos")

La clase Alumno consta de dos variables de clase (Alumno.numalumnos y Alumno.sumanotas) que son accesibles desde los métodos de la clase. Además, sus valores son compartidos por todas las instancias que existan de esta clase.

A continuación, se declaran varios métodos (funciones) que incluyen como primer argumento a self que contiene la referencia del objeto especifico que llama al método en un momento dado. Como su valor es implícito cuando se llama a un método no es necesario pasar este argumento.

El método __init__() es especial porque se ejecuta automáticamente cada vez que se crea una nuevo objeto. Este método, que es opcional, se llama constructor y se suele utilizar para inicializar las variables de las instancias (en este caso para inicializar las variables self.nombre y self.nota).

El resto de métodos se utilizan para acceder y mostrar el valor de las variables de clase y de instancia. Por último, el método mostrarNotaMedia() realiza un cálculo y después muestra su resultado.

Crear objetos (instancias) de una clase

Para crear instancias de una clase se llama a la clase por su propio nombre pasando los argumentos que requiera el método constructor __init__ si existe.


alumno1 = Alumno("Maria", 8)
alumno2 = Alumno("Carlos", 6)

Todos los argumentos se pasan escribiéndolos entre paréntesis y separados por comas (","). El primer argumento self se omite porque su valor es una referencia al objeto y es implícito para todos los métodos.

Accediendo a los atributos y llamando a los métodos

Para acceder a la variable de un objeto se indica el nombre del objeto, seguido de un punto y el nombre de la variable:


print(alumno1.nombre)  # María
print(alumno1.nota)  # 8

Para modificar la variable de un objeto se utiliza la misma notación para referirse al atributo y después del signo igual (=) se indica la nueva asignación:


alumno1.nombre = "Carmela"

Para acceder a las variables de la clase se sigue la misma notación pero en vez de indicar el nombre del objeto se indica el nombre de la clase instanciada.

print(Alumno.numalumnos)  # 2
print(Alumno.sumanotas)  # 14

Para llamar a un método se indica el nombre de objeto, seguido de un punto y el nombre del método. Si se requieren varios argumentos se pasan escribiéndolos entre paréntesis, separados por comas (","). Si no es necesario pasar argumentos se añaden los paréntesis vacíos "()" al nombre del método.


print(alumno1.mostrarNombreNota())  # ('Carmen', 8)
print(alumno2.mostrarNombreNota())  # ('Carlos', 6)

Para suprimir un atributo:


del alumno1.nombre

Si a continuación, se intenta acceder al valor del atributo borrado o se llama a algún método que lo utilice, se producirá la siguiente excepción:


print(alumno1.mostrarNombreNota())

AttributeError: 'Alumno' object has no attribute 'nombre'

Pare crear nuevamente el atributo realizar una nueva asignación:


alumno1.nombre = "Carmen"

Vídeo sobre clases y objetos: https://www.youtube.com/watch?v=VYXdpjCZojA


No hay comentarios:

Publicar un comentario