Tutorial de descriptores de Python

Tutorial de descriptores de Python
Una técnica útil para escribir código genérico que podría reutilizarse entre las clases es compatible con los descriptores de Python, o más comúnmente conocido como descriptores. Pueden sonar cerca de la noción de herencia, pero no están. Esta es una técnica directa para capturar el acceso a los atributos con una naturaleza vinculante. Los descriptores son una función básica de Python que gobierna gran parte de la brujería, oculta bajo la portada del idioma. Si alguna vez ha sentido que los descriptores de Python con pequeñas implementaciones funcionales son un tema avanzado, entonces este tutorial es la plataforma definitiva para hacerle comprender esta poderosa característica.

Métodos descriptores

Para indicarlo claramente, una clase que implementa __conseguir_(), __colocar()_, o __borrar()_ La función de un protocolo de descriptor para un objeto se clasifica como un "descriptor". Para gobernar los parámetros de varias clases que usan el objeto como referencia, se hacen los descriptores de Python. Aquí hay tres métodos especificados, que se utilizarán en descriptores:

__conseguir__(): Cuando intenta extraer los datos, el __conseguir__() Se llama al atributo, y lo que proporcione es lo que se proporcionaría al código que exige el valor de una variable. Se clasifica como un descriptor que no es de datos y solo es legible.

__colocar__(): La función __colocar__() está llamado a ajustar los valores de los parámetros, y esta función le devuelve nada. Se conoce como un descriptor de datos que no solo es legible sino que también es escrito.

__borrar__(): Cada vez que se elimina el parámetro de un objeto, el __borrar__() se llama función. Se conoce como un descriptor de datos que no solo es legible sino que también es escrito.

Solo necesita hacer cumplir el protocolo de descriptor si está utilizando descriptores de Python en su script. Las funciones más importantes del protocolo son conseguir() y colocar() tener la firma posterior.

__get __ (self, obj, type = none) -> objeto
__set __ (self, obj, valor) -> ninguno

ser es la instancia del descriptor.
obj es una instancia del objeto al que está conectado su descriptor.
tipo es el tipo de objeto.

Ejemplo:

Aquí hemos definido dos clases. En el descriptor de clase, hemos definido métodos de descriptor. En el conseguir() Método, el yo es la instancia del descriptor 'val', obtendrá un valor 'geeks' y lo almacena. Luego hará una cadena con 'para' adjunto entre el atributo provisto. Descriptor de clases (objeto):

def __get __ (self, obj, objtype):
volver para".formato (yo mismo.Val, yo.val)

Luego devolverá el valor al método set (). Esta función luego verifica el valor, ya sea una cadena o no. En caso de que el valor sea una cadena, se guardará en un atributo llamado 'Val'. Si el valor no es una cadena, lanzará una excepción.

def __set __ (self, obj, val):
Si es Isinstance (Val, Str):
ser.val = val
demás:
elevar typeError ("El nombre debe ser cadena")

Después de eso, el valor se imprimirá como una cadena 'geeksforgeeks'.

clase GFG (objeto):
val = descriptor ()
g = gfg ()
gramo.val = "Geeks"
Imprimir (G.val)

Cuando intente ejecutar este código, obtendrá la siguiente salida:

Geeksforgeeks

Propósito de los descriptores

Describamos una clase llamada 'Home' con tres características, a saber: LOC, área y precio. Puedes usar la función __en eso__() Para inicializar los atributos de clase.

Casa de clase:

def __init __ (self, loc, área, precio):

Luego, puede usar la función __STR __ (), que podría devolver el resultado de los tres atributos que puede pasar a la clase al construir el elemento. La función __str __ () devolverá la cadena.

Cuando ejecuta este código, mostrará la salida aparentemente correcta.

Ahora intentemos cambiar el precio de la casa a un valor negativo, como se muestra a continuación, y ejecute el código.

No hay ningún cambio en absoluto, excepto el signo negativo, como se muestra en la salida. Aférrate! Algo está fuera de aquí, ¿no?? ¿Cómo es que el precio de una casa es negativo?. Python lo permite porque Python es un entorno de desarrollo versátil que específicamente no permite verificar tipo.

Inicialicemos una declaración 'si' en __en eso__() función para aumentar una excepción si el valor o el precio es inferior a cero.

A partir de ahora, puede notar que funciona bien, y si el precio es inferior a cero, el código genera un error de valor.

Como podemos entender, el __en eso_() la función es un constructor, y solo se invoca una vez cuando hace un objeto de clase. Por lo tanto, más tarde, la verificación de tipo personalizada fallaría. Python proporciona descriptores que se especializan en ayudar a arreglar todas las preocupaciones anteriores. Ahora, comencemos a usar descriptores en el mismo ejemplo para entenderlo bien.

La clase descriptor ' __en eso_() La función tiene una variable local __pricio a las 0. Al comienzo de la misma, un doble subrayamiento implica que el parámetro es privado. Se utiliza para diferenciar el parámetro de precio de la clase de descriptor de la clase de inicio.

El __conseguir__() El método devolverá el precio. La instancia de atributo contiene H1, que es una instancia descriptora. El propietario del atributo se refiere al nombre de la clase 'Inicio' y devuelve el precio.

La función __colocar__() tiene un atributo instancia que contiene H1 y un valor a asignar. El cheque se usa para confirmar el valor. Si el valor es un número entero, se imprimirá, de lo contrario, el código con una excepción de error de Tipo de tipo. Si el valor es inferior a cero, la excepción de error de valor se lanzará al código.

El __borrar__() la función se ejecuta cuando el atributo de parámetro se elimina de un objeto.

La clase de origen permanece igual, aunque la instancia precio de la clase Descriptor () se agrega. En el __en eso_() función, agregue el atributo de precio al precio de la instancia y llamará al __colocar_() función.

Al ejecutar este código, le dará un error de valor porque el precio nunca puede ser cero.

Ahora intente ejecutar el código con un valor de cadena.

Lanzará una excepción de error de tipo.

El valor de instancia existente se anula en la formación de una nueva instancia ya que los descriptores están relacionados con la clase y no con la instancia. Echa un vistazo a continuación:

El primer valor ha sido anulado con el segundo.

Conclusión

Podemos comprender por qué los descriptores de Python se han convertido en un tema tan fascinante y a qué tipo de escenarios de uso puede agregarlos al pasar por este tutorial.