Maison >développement back-end >Tutoriel Python >Concepts Python avancés - Métaprogrammation
Imaginez écrire un code Python qui peut se modifier ou générer dynamiquement un nouveau code en fonction de la saisie de données en temps réel. La métaprogrammation est une technique de programmation puissante et avancée qui permet aux développeurs d'écrire du code capable de manipuler d'autres codes et de générer un nouveau code pendant l'exécution. Comme nous le disons, les métadonnées sont des données de données, et la métaprogrammation consiste également à écrire du code qui manipule du code. Par conséquent, cet article traite des capacités de métaprogrammation pour améliorer l'efficacité et la flexibilité du code. Nous en apprendrons davantage sur sa fondation, ses décorateurs, ses métaclasses et l'exécution de code dynamique en fournissant des exemples pratiques de chaque concept. Commençons !
En Python, la métaprogrammation consiste à écrire des programmes informatiques qui aideront à écrire et à manipuler d'autres programmes. Cette technique permet aux programmes de traiter d'autres programmes comme des données. Il génère le code, modifie le code existant et crée une nouvelle construction de programmation au moment de l'exécution.
Avant de passer aux aspects techniques des concepts de métaprogrammation, voyons d'abord en quoi la programmation générique ou régulière basée sur des étapes procédurales diffère du concept de programmation avancée.
La métaprogrammation nous offre de nombreux avantages. Explorons-les pour comprendre leur avantage dans le processus de développement.
Semblable aux avantages, la métaprogrammation présente également certains inconvénients, que le développeur garde à l'esprit avant d'utiliser cette technique.
Une métaclasse définit le comportement et la structure des classes. À l’aide des métaclasses en Python, vous pouvez facilement personnaliser la création et le comportement des classes. Cela est possible car Python représente tout, y compris les classes, en tant qu'objet. De plus, l'objet est créé à l'aide de la classe. Par conséquent, cette supposée « classe » agit comme une classe enfant d’une autre classe qui est une métaclasse et une super classe. De plus, toutes les classes Python sont des classes enfants de métaclasses.
Remarque :
Type est la métaclasse par défaut en python. Il est utilisé pour créer des classes dynamiquement.
En Python, les métaclasses sont par défaut une classe "type" c'est à dire une classe de base qui sert à gérer la création et le comportement des classes. Lors de la création de la classe en Python, nous avons indirectement utilisé la classe "type". La métaclasse se compose de deux méthodes principales : __new__ et __init__. La méthode __new__ est utilisée pour créer un nouvel objet. Cette méthode crée et renvoie l'instance, qui est ensuite transmise à la méthode __init__ pour l'initialisation. Elle est appelée avant la méthode __init__ et assure le contrôle de création de la classe elle-même. Ensuite, la méthode __init__ est utilisée après la création d'une nouvelle classe pour l'initialiser avec d'autres attributs et méthodes. Cette méthode est assez différente de la méthode de programmation classique. Il nous permet de modifier et de définir les attributs au niveau de la classe après la création de la classe.
Conseil :
Les méthodes new et init sont utilisées pour créer les classes personnalisées et leur comportement
Comprenons avec un simple exemple Python comment nous pouvons créer des métaclasses personnalisées pour personnaliser la création de classe et son comportement à l'aide des méthodes primaires des métaclasses __new__ et __init__.
# Define the metaclass class Meta(type): #define the new method for creating the class instance #cls: metaclass whose instance is being created #name: name of the class #base: means the base class #class_dict: represent the dictionary of attributes for a class def __new__(cls, name, bases, attrs): #making the attributes(method) name as upper case uppercase_attrs = {key.upper(): value for key, value in attrs.items() if not key.startswith('__')} new_class = super().__new__(cls, name, bases, uppercase_attrs) print("Class {name} has been created with Meta") return new_class #the class is initialized def __init__(cls, name, bases, dct): super().__init__(name, bases, dct) print(f"Class {name} initilized with Meta") # Using the metaclass in a new class class MyClass(metaclass=Meta): def my_method(self): print(f"Hello!") # Instantiate MyClass and access its custom attribute obj = MyClass() #here the attribute of the class is change into uppercase i.e. the name of method obj.MY_METHOD()
Sortie
Remarque :
N'oubliez pas que dans le résultat, la chaîne "Bonjour" ne sera pas convertie en majuscules, mais le nom de la méthode "ma_méthode" en "MY_METHOD" qui imprimera la chaîne. Cela signifie que nous convertissons le nom de la méthode en majuscule.
Les décorateurs sont les fonctionnalités clés de la métaprogrammation Python. Les décorateurs sont une fonctionnalité puissante qui permet aux développeurs de modifier le code existant sans changer le code source d'origine. Il vous permet d'ajouter de nouvelles fonctionnalités en étendant la fonction existante. Les décorateurs sont généralement exécutés sur des fonctions et leur syntaxe utilise le symbole « @ » avec le nom de la fonction du décorateur avant son code. En Python, les décorateurs agissent comme un wrapper autour d'autres fonctions et classes. L'entrée et la sortie du décorateur sont la fonction elle-même, exécutant généralement la fonctionnalité avant et après la fonction d'origine.
Les décorateurs utilisent le @decorator_name comme syntaxe. Alors que decorator_name est le nom de la fonction que vous effectuez en tant que décorateur.
# Define the metaclass class Meta(type): #define the new method for creating the class instance #cls: metaclass whose instance is being created #name: name of the class #base: means the base class #class_dict: represent the dictionary of attributes for a class def __new__(cls, name, bases, attrs): #making the attributes(method) name as upper case uppercase_attrs = {key.upper(): value for key, value in attrs.items() if not key.startswith('__')} new_class = super().__new__(cls, name, bases, uppercase_attrs) print("Class {name} has been created with Meta") return new_class #the class is initialized def __init__(cls, name, bases, dct): super().__init__(name, bases, dct) print(f"Class {name} initilized with Meta") # Using the metaclass in a new class class MyClass(metaclass=Meta): def my_method(self): print(f"Hello!") # Instantiate MyClass and access its custom attribute obj = MyClass() #here the attribute of the class is change into uppercase i.e. the name of method obj.MY_METHOD()
La syntaxe est également utilisée comme suit, qui montre le décorateur prenant une fonction comme argument et enregistre le résultat dans une autre fonction.
@decorator_name def function_name():
Vous trouverez ci-dessous un exemple d'utilisation de décorateurs pour convertir la chaîne d'une fonction en majuscule, ce qui signifie ajouter la fonctionnalité majuscule à la fonction :
Function_name = decorator_name(function_name)
Sortie
Dans le monde de la métaprogrammation, inspection et réflexion sont des termes clés. L'inspection est effectuée pour examiner le type et la propriété d'un objet dans un programme et fournir un rapport à ce sujet au moment de l'exécution. En revanche, la réflexion implique de modifier la structure et le comportement d'un objet au moment de l'exécution. Ces deux fonctionnalités du langage font de Python un langage dynamique fortement typé. Nous pouvons effectuer une inspection et une réflexion en métaprogrammation en utilisant le module "inspect". Ce module fournit diverses fonctions d'introspection, notamment des informations sur le type et la propriété d'un objet, le code source et la pile d'appels.
Comprenons qu'en utilisant le module "inspect" d'introspection et de réflexion combiné à d'autres fonctionnalités Python, nous pouvons examiner et modifier l'objet au moment de l'exécution en métaprogrammation. Nous l'apprendrons étape par étape :
# Define the metaclass class Meta(type): #define the new method for creating the class instance #cls: metaclass whose instance is being created #name: name of the class #base: means the base class #class_dict: represent the dictionary of attributes for a class def __new__(cls, name, bases, attrs): #making the attributes(method) name as upper case uppercase_attrs = {key.upper(): value for key, value in attrs.items() if not key.startswith('__')} new_class = super().__new__(cls, name, bases, uppercase_attrs) print("Class {name} has been created with Meta") return new_class #the class is initialized def __init__(cls, name, bases, dct): super().__init__(name, bases, dct) print(f"Class {name} initilized with Meta") # Using the metaclass in a new class class MyClass(metaclass=Meta): def my_method(self): print(f"Hello!") # Instantiate MyClass and access its custom attribute obj = MyClass() #here the attribute of the class is change into uppercase i.e. the name of method obj.MY_METHOD()
Sortie
@decorator_name def function_name():
Sortie
C'est ainsi que vous pouvez examiner et effectuer des modifications de manière dynamique au moment de l'exécution. L'utilisation du module inspect combiné aux fonctions intégrées de Python telles que setattr et delattr permettra au développeur d'écrire de manière flexible et adaptative qui peut changer au moment de l'exécution.
Conseil :
setattr et delattr sont des fonctions Python permettant de modifier dynamiquement les attributs d'objet. Dans ces fonctions, setattr est utilisé pour définir et modifier l'attribut, et delattr est utilisé pour supprimer l'attribut d'un objet.
Comme nous le savons, le débogage est bien plus fastidieux et prend plus de temps que l'écriture du code du premier coup. Les développeurs déboguent le code pour vérifier et trouver les sources des défauts afin de les gérer dès les premiers stades. Cependant, il s’agit d’un processus très hétérogène dont on ne peut pas identifier la source. Par conséquent, l’introspection et la réflexion sont très utiles pour déboguer le code. Il examine l'objet de manière dynamique au moment de l'exécution en fournissant des détails sur la nature de l'objet, y compris son comportement. Il fournit des détails sur les valeurs d'attribut d'objet et les valeurs inattendues et explique comment l'état de l'objet change au fil du temps. Pour rendre cela plus clair, utilisons un exemple.
Function_name = decorator_name(function_name)
Sortie
Pour résumer, nous avons discuté du concept avancé de Python, qui est la métaprogrammation. Comme nous le savons, la métaprogrammation est constituée des techniques qui étendent et modifient le comportement du langage Python lui-même. Cela peut vous aider à écrire des fonctions qui peuvent modifier et générer d'autres fonctions. Nous pouvons effectuer de la métaprogrammation en utilisant différentes approches, comme les métaclasses nous permettent d'utiliser la classe de type par défaut, puis le décorateur, qui agit comme le wrapper d'une autre fonction et passe aux techniques. pour déboguer le code au préalable. Ainsi, partout où vous vous dirigez vers les concepts avancés de Python, n'oubliez pas de vous renseigner également sur la signification de la métaprogrammation. J'espère que ce guide vous sera utile. Merci d'avoir lu. Bon codage !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!