Class variables

Aquí diferenciaremos lo que es una variable de una instancia de lo que es una variable de una clase.

Como su nombre lo indica, la variable de clase afecta a todas las intancias de la clase.

Recordar: una variable de instancia es única para cada instancia

Tenemos creada la clase de Empleados y ahora, por convenio salarial, se fima un incremento general del salario de un tanto %, para todos los empleados.

Esta "variable" es común para todos los empleados.

Una primera forma es crear un método que ya incluya ese incremento salarial, e.g. un $10\%$.

Esta sería una manera bruta de hacerlo

Si bien obtenemos el incremento salarial, hay dos problemas:

1.- Hay que entrar en el código para modificar el porcentaje de incremento. Eso hace complejo y de facil error el script.

2.- No hay forma de sacar, como atributo, el incremento de salario, e.g., ya sea mediante emp_1.tasa_incremento_salarial o, como es algo que afecta a toda la clase Empleados.tasa_incremento_salarial por que no existe.

Vamos a crear una class variable y escribir el código para ello

Pone un name error: la variable no está definida.

Cuando accedemos a las variables de clase, debemos acceder por medio de la clase, i.e., Empleados.tasa_incremento_salarial o mediante una instancia de una clase (self, pero esta última es confusa, ya que hace referencia a la instancia cuando es una variable de clase, por ello tenemos que tener claro cuando lo haremos)

Veamos que podemos acceder a la variable de clase tanto desde la clase como desde las instancias

Scope: cuando accedemos a un attributo de una instancia, primero busca en el local, es decir, si la instancia tiene definida ese atributo.

Si no lo tiene, lo busca en el enclosing, que es la clase que lo ha construido.

Veamos el namespace de una instancia y veremos que no tiene definido el atributo tasa_incremento_salarial

¿Que pasa si cambia el porcentaje de incremento?

Cambia para la clase y para las instancias.

Qué pasaría si lo hacemos para una sola instancia.

Cuando se escribe emp_1.tasa_incremento_salarial se crea el atributo particular para la instancia (mirar que antes, no lo tenia)

Esto puede afectar los métodos que incluyen variables de clase, según como los definamos, e.g.

Con referencia a la clase

def incremento_salarial(self):
        self.salario = int(self.salario * Empleados.tasa_incremento_salarial)

o con referencia a la instancia

def incremento_salarial(self):
        self.salario = int(self.salario * self.tasa_incremento_salarial)

Vamos a modificar la clase y poner self para poder individualizar el incremento salarial.

Además, como veremos, esto permitirá a una subclase modificar esta constante.

Veamos un ejemplo donde no tiene sentido utilizar la instancia self por que hace referencia a algo que es general.

Por ejemplo, el número total de empleados

Vamos a crear una variable de clase, num_de_emps y, como inicialización, le daremos el valor $0$.

A medida que creamos empleados, vamos añadiendo valores a esta función.

Como cada empleado es una instancia que se crea con el constructor __int__ incrementaremos (redefiniremos) este valor cada vez que se cree una nueva instancia.

Métodos especiales

Python proporciona métodos especiales que resultan útiles.

Por ejemplo, recuerda que las listas y tuplas tienen una noción de longitud y que esta longitud puede ser consultada mediante la función len

Si desea proporcionar un valor de retorno para la función len cuando se aplica a su objeto definido por el usuario, utilice el método especial __len__.

Por tanto, tenemos

Un método especial que se usa regularmente es el método __call__.

Este método se puede utilizar para hacer que tus instancias sean callables, al igual que las funciones

Entonces, creamos la instancia f y vemos que es una función, ya que la puedo llamar

Ejercicio

1.- Dado el polinomio

$$ p(x) = a_0 + a_1 x + a_2 x^2 + \cdots a_N x^N = \sum_{n=0}^N a_n x^n \qquad (x \in \mathbb{R}) \tag{1} $$

Escriba la función p(x, coeff) para que evalue el polinomio (1) en un punto $x$ y para un conjunto de coeficientes $(a_0,...,a_N)$

2.- Ahora escriba una clase, llamada Polynomio para representar y manipular polinomis tipo (1)

Ayuda: La instancia serán los coeficientes del polinomio, i.e., los números $(a_0, \ldots, a_N )$.

Debe haber dos métodos:

A. Que evalue el polinomio en un punto, i.e., que retorne $p(x)$ para cada $ x $.

B. Que retorne la derivada del polinomio reemplazando los coeficientes por los de su derivada $ p' $.

Posible solucion