Tutoriel des descripteurs Python

Tutoriel des descripteurs Python
Une technique utile pour écrire du code générique qui pourrait être réutilisé entre les classes est prise en charge par des descripteurs Python, ou plus communément appelés descripteurs. Ils peuvent sembler près de la notion d'héritage, mais ils ne sont pas. Ceci est une technique directe pour capturer l'accès aux attributs avec une nature contraignante. Les descripteurs sont une fonction de base de Python qui régit une grande partie de la sorcellerie, cachée sous la couverture de la langue. Si vous avez déjà pensé que les descripteurs Python avec peu d'implémentations fonctionnelles sont un sujet avancé, alors ce tutoriel est la plate-forme ultime pour vous faire comprendre cette fonctionnalité puissante.

Méthodes de descripteur

Pour le dire clairement, une classe qui implémente __obtenir_(), __ensemble()_, ou __supprimer()_ La fonction d'un protocole de descripteur pour un objet est classée comme un «descripteur». Pour régir les paramètres de différentes classes qui utilisent l'objet comme référence, des descripteurs Python sont fabriqués. Voici trois méthodes spécifiées, qui seront utilisées dans les descripteurs:

__obtenir__(): Lorsque vous essayez d'extraire les données, le __obtenir__() L'attribut est appelé, et tout ce qu'il fournit est ce qui serait fourni au code exigeant la valeur d'une variable. Il est classé comme un descripteur non de données et est uniquement lisible.

__ensemble__(): La fonction __ensemble__() est appelé pour ajuster les valeurs des paramètres, et rien ne vous est renvoyé par cette fonction. Il est connu comme un descripteur de données qui est non seulement lisible mais aussi écrite.

__supprimer__(): Chaque fois que le paramètre est supprimé d'un objet, le __supprimer__() La fonction est appelée. Il est connu comme un descripteur de données qui est non seulement lisible mais aussi écrite.

Vous n'avez qu'à appliquer le protocole de descripteur si vous utilisez des descripteurs Python dans votre script. Les fonctions les plus importantes du protocole sont obtenir() et ensemble() Avoir la signature suivante.

__get __ (self, obj, type = aucun) -> objet
__set __ (self, obj, valeur) -> Aucun

soi est l'instance du descripteur.
obj est une instance de l'objet auquel votre descripteur est connecté.
taper est le type d'objet.

Exemple:

Ici, nous avons défini deux classes. Dans le descripteur de classe, nous avons défini des méthodes de descripteur. Dans le obtenir() Méthode, le Soi est l'instance du descripteur «Val», il obtiendra une valeur «geeks» et le stockera. Ensuite, il fera une chaîne avec «pour» attaché entre l'attribut fourni. Descripteur de classe (objet):

def __get __ (self, obj, objtype):
Retour pour".format (soi.Val, soi.val)

Il renverra ensuite la valeur à la méthode set (). Cette fonction vérifie ensuite la valeur, qu'il s'agisse d'une chaîne ou non. Dans le cas où la valeur est une chaîne, elle sera enregistrée dans un attribut nommé 'Val'. Si la valeur n'est pas une chaîne, elle lancera une exception.

def __set __ (self, obj, val):
Si Isinstance (Val, Str):
soi.val = val
autre:
River TypeError («Le nom doit être une chaîne»)

Après cela, la valeur sera imprimée en tant que chaîne «Geeksforgeeks».

classe GFG (objet):
val = descripteur ()
g = gfg ()
g.val = "geeks"
imprimer (g.val)

Lorsque vous essayez d'exécuter ce code, vous obtiendrez la sortie suivante:

Geeksforgeeks

But des descripteurs

Décrivons une classe nommée «Home» avec trois caractéristiques, à savoir: LOC, zone et prix. Vous pouvez utiliser la fonction __init __ () Pour initialiser les attributs de classe.

Maison de classe:

Def __init __ (self, loc, zone, prix):

Ensuite, vous pouvez utiliser la fonction __str __ (), qui pourrait retourner le résultat des trois attributs que vous pourriez transmettre à la classe lors de la construction de l'article. La fonction __str __ () renvoie la chaîne.

Lorsque vous exécutez ce code, il affichera la sortie apparemment correcte.

Essayons maintenant de modifier le prix de la maison à une valeur négative, comme ci-dessous, et exécuter le code.

Il n'y a aucun changement du tout, à l'exception du signe négatif, comme indiqué dans la sortie. Attendez! Quelque chose est parti ici, n'est-ce pas? Comment se fait-il que le prix d'une maison soit négatif. Python le permet car Python est un environnement de développement polyvalent qui ne permet pas spécifiquement la vérification du type.

Initialisons une déclaration «si» dans __init __ () fonction pour augmenter une exception si la valeur ou le prix est inférieur à zéro.

Pour l'instant, vous remarquerez peut-être qu'il fonctionne bien, et si le prix est inférieur à zéro, le code génère une erreur de valeur.

Comme nous pourrions comprendre, le __init_ () La fonction est un constructeur et n'est invoqué qu'une fois que lorsque vous faites un objet de classe. Par conséquent, plus tard, la vérification de type personnalisée échouerait. Python fournit des descripteurs spécialisés dans l'aide à résoudre toutes les préoccupations ci-dessus. Maintenant, commençons à utiliser des descripteurs dans le même exemple pour bien le comprendre.

La classe descripteurs ' __init_ () La fonction a une variable locale __price à 0. Au début, un double soulignement implique que le paramètre est privé. Il est utilisé pour différencier le paramètre de prix de la classe descripteurs de la classe à domicile.

Le __obtenir__() La méthode rendra le prix. L'instance d'attribut contient H1, qui est une instance de descripteur. Attribut Le propriétaire fait référence au nom de la classe «à la maison» et à retourner le prix.

La fonction __ensemble__() a un attribut exemple qui contient H1 et une valeur à attribuer. Le chèque est utilisé pour confirmer la valeur. Si la valeur est un entier, elle sera imprimée, sinon, le code avec exception de type d'erreur de type. Si la valeur est inférieure à zéro, l'exception d'erreur de valeur sera jetée dans le code.

Le __supprimer__() La fonction est exécutée lorsque l'attribut de paramètre est supprimé d'un objet.

Le cours à domicile reste le même, bien que l'instance prix de la classe descripteur () est ajouté. Dans le __init_ () fonction, ajouter l'attribut de prix au prix de l'instance et il appellera le __ensemble_() fonction.

Lors de l'exécution de ce code, il vous donnera une erreur de valeur car le prix ne peut jamais être nul.

Essayez maintenant d'exécuter le code avec une valeur de chaîne.

Il lancera une exception d'erreur de type.

La valeur d'instance existante est remplacée sur la formation d'une nouvelle instance car les descripteurs sont liés à la classe et non à l'instance. Jetez un œil ci-dessous:

La première valeur a été remplacée par la seconde.

Conclusion

Nous pouvons comprendre pourquoi les descripteurs de Python sont devenus un sujet tellement fascinant et quel type de scénarios d'utilisation auxquels vous pouvez les ajouter en passant par ce tutoriel.