Getters and Setters en Python



@eduardo_gpg

Número de visitas 6622

Tiempo de lectura 4 min

28 Marzo 2022

En entregas anteriores ya hemos hablado sobre el manejo de atributos en Python. Puntualmente me refiero a los siguientes artículos.

Pues bien, siguiente con el tema, en esta ocasión me gustaría hablaremos sobre cómo poder implementar los ya famosos métodos getters and setters en Python.

Métodos los cuales, como veremos más adelante, tienen el objetivo de implementar el tema de encapsulamiento para nuestras clases. 🤖

Bien, una vez dicho todo esto, y sin mayor introducción, comencemos con el post.

Métodos getters and Setters. 🕵️‍♀️

De lo primero que debemos hablar es sobre los métodos getters and setters. Verás, estos métodos tienen como objetivo fungir como interfaces con las cuales, respectivamente, se podrán obtener y asignar nuevos valores a atributos de la clase. De tal forma que estas acciones (obtener y asignar valores) se realicen únicamente dentro de la clase, asegurando así el tema de encapsulamiento.

Estos métodos son muy comunes en lenguajes de programación orientados a objetos. En Java, por ejemplo, es una muy buena practica tener un par de estos métodos por cada uno de los atributos del objeto.

Es más, inclusive hay IDEs, como NetBeans o Eclipse, generan de forma automática estos métodos por cada uno de los atributos en la clase. 😯

Ejemplo.

public class User{

    private String username;
    private String email;

    public String getUsername() {
        return this.username;
    }

    public String setUsername(String username) {
        this.username= username;
    }

    public String getEmail() {
        return this.email;
    }

    public String setEmail(String email) {
        this.email= email;
    }
}

En este ejemplo podemos observar 2 atributos privados. Por cada uno de estos atributos se genera el par de métodos getters and __setter_. Con estos nos aseguramos que la única forma de poder obtener y/o modificar estos atributo sea dentro de la misma clase. Obligatoriamente haciéndolo por estos métodos. 🙌

Implementación en Python

Listo, ya tenemos conocimientos de los métodos getters and setters. Ahora quizás te estés preguntando ¿Cómo podemos implementar estos métodos en Python?

Estas es una pregunta muy común, y valida, en desarrolladores, y desarrolladoras, que ya tienen conocimientos de un lenguaje de programación orientada a objetos y desean comenzar a dar sus primeros pasos en Python. 🤓

Si bien, nosotros podemos generar dichos métodos sin ningún problema.

class User:

    def __init__(self, username: str):
        self.__username = username


    def set_username(self, username: str) -> None:
        self.__username = username


    def get_username(self) -> str:
        return self.__username

Hay que tener en cuanta que este no es código Pythonico. 🤷‍♀️

La idea de estos métodos es proveer un acceso a los atributos privados de una clase. Sin embargo, si recordamos en el post Atributos privados se menciono que los atributos privados en Python no existen. Por lo cual, intentar implementar estos métodos carece de lógica.

Sí, se que estos puede ser algo decepciónate, pero es así. 😣

Lo que si podemos hacer es implementar otro tipo de mecanismo para poder obtener y actualizar los atributos de una clase. Estos mediante propiedades.

Properties

Siguiendo con el ejemplo anterior, para simular los métodos getters and setters vamos a crear un nuevo método para nuestra clase. Este método deberá tener por nombre el nombre de un atributo y será decorado por @property.

class User:

    def __init__(self, username):
        self.username = username


    @property
    def username(self):
        return self.__username

Al nosotros decorar con @property le estaremos indicando a Python que el método deberá ser tratado como un atributo. Un Atributo únicamente de lectura.

El método se encargará de retornar el valor que deseemos sea consultado.

Ejemplo.

>>> user = User('eduardo_gpg')
>>> user.username
eduardo_gpg

Los métodos decorados con @property, reitero, serán únicamente de lectura. Si intentamos asignar un valor obtendremos un error.

>>> user = User('eduardo_gpg')
>>> user.username = 'Nuevo username'

Traceback (most recent call last):
  File "main.py", line 19, in <module>
    user.username = 'Nuevo username'
AttributeError: can't set attribute

Ahora, para que nosotros podamos tener un propiedad que permita asignar un valor, vamos a decorar un nuevo método con setter. Este nuevo método es recomendable tenga el mimo nombre que el método de lectura. La diferencia entre este nuevo método es que deberá poseer un parámetro obligatorio; con el cual se podrá realizar la asignación de valor.

Ejemplo.

@username.setter 
def username(self, value):
    self.__username = value

Setter es un método de la propiedad, es por ello que decoramos con @username.setter. Donde username es el método decorado con @property.

Es decir, para poder tener un "atributo" para asignar un valor, obligatoriamente debemos tener un "atributo" de lectura.

Ahora sí, con este nuevo método ya podremos asignar y obtener el valor de nuestro atributo "privado" ( __username).

>>> user = User('eduardo_gpg')
>>> user.username = 'Nuevo username'
>>> user.username
Nuevo username

Será a través de propiedades que un usuario podrá obtener o actualizar el valor de un atributo "privado" en Python. 🐛

Callbacks

Lo interesante de trabajar con métodos como propiedades, es que tenemos la oportunidad de implementar lógica de programación cuando se obtenga o asigne algún tipo de valor.

Veamos un par de ejemplos.

class User:

    def __init__(self):
        self.__username = ''


    @property
    def username(self):
        return self.__username


    @username.setter 
    def username(self, value):
        assert len(value) > 6, 'Lo sentimos, el username debe poseer por lo menos 6 caracteres.'
        self.__username = value

Para este ejemplo implemento una pequeña validación. Si el string que se desea asignar tiene una longitud menor a 6 caracteres un error será lanzado.

Traceback (most recent call last):
  File "main.py", line 18, in <module>
    user.username = 'a'
  File "main.py", line 14, in username
    assert len(value) > 6, 'Lo sentimos, el username debe poseer por lo menos 6 caracteres.'
AssertionError: Lo sentimos, el username debe poseer por lo menos 6 caracteres.}

Nosotros por supuesto podemos implementar cualquier tipo de lógica de programación que deseemos. Ya sea cuando se obtenga o asigne un valor. 🍻

Conclusión

Como pudimos aprender a lo largo del post, los métodos getters and setters en Python no pueden ser implementados tal y como los conocemos. Lo que si podemos hacer para no exponer ciertos atributos de la clase es trabajar con properties. Los cuales nos permitirán obtener o asignar valores a nuestro atributos. 🤩


¿El contenido te resulto de ayuda?

Para poder dejar tu opinión es necesario ser un usuario autenticado. Login

Más Tips y Ejercicios 🐍

Adquiere una subscripción PyWombat por tan solo $3 USD. al mes.

Conoce los beneficios de ser usuario premium:
Niveles desbloqueados: Ten accesos a todos los niveles de ejercicios. 🔓
Nuevo límite: Incrementa tu límite de ejercicios por semana. 🚀
Contenido único: Recibe semanalmente recursos exclusivos de Python (Videos, Artículos y Capitulos del libro PyWombat, comienza como desarrollador Python. 🐍