getattr() en Python - accéder aux attributs dynamiques

Denis Ribeiro .

6 octobre 2026

Code Python montrant une classe `Student` avec `__init__` et `__repr__`. On peut utiliser `getattr` pour accéder aux attributs `name` et `age`.

Lorsqu’un nom d’attribut est connu seulement au moment de l’exécution, l’accès classique avec le point ne suffit plus. La fonction getattr() permet alors de lire dynamiquement un attribut, une méthode ou une valeur de configuration, tout en contrôlant le comportement si cet élément n’existe pas. Je détaille ici sa syntaxe, ses usages concrets, ses différences avec hasattr() et les pièges qui peuvent rendre le code difficile à maintenir.

Retenir l’essentiel sur getattr en Python

  • getattr() récupère un attribut à partir de son nom sous forme de chaîne.
  • Sa forme complète est getattr(objet, nom, valeur_par_défaut).
  • Sans valeur par défaut, un attribut absent provoque une AttributeError.
  • La fonction peut aussi récupérer une méthode, qu’il est ensuite possible d’appeler.
  • Elle est utile pour les configurations, les plugins et la sérialisation, mais doit rester lisible et contrôlée.

Comprendre ce que fait réellement getattr

En Python, getattr() est une fonction intégrée qui cherche un attribut sur un objet à partir d’un nom texte. La syntaxe minimale est simple :

getattr(objet, "nom_attribut")

Dans cet exemple, Python cherche l’attribut appelé nom_attribut et renvoie sa valeur. Le résultat peut être une chaîne, un nombre, une liste, une propriété ou même une méthode. C’est cette souplesse qui rend la fonction intéressante pour le code dynamique.

class Utilisateur:
    def __init__(self):
        self.nom = "Claire"
        self.age = 31

utilisateur = Utilisateur()

print(getattr(utilisateur, "nom"))
print(getattr(utilisateur, "age"))

Le programme affiche ici Claire puis 31. L’écriture directe utilisateur.nom serait plus courte, mais elle ne fonctionnerait pas si le nom de l’attribut était stocké dans une variable.

attribut = "nom"
valeur = getattr(utilisateur, attribut)

print(valeur)

Dans mes propres scripts, c’est généralement le critère qui guide le choix. Si le nom est fixe, l’accès avec le point reste plus clair. Si le nom vient d’un fichier de configuration, d’un formulaire ou d’une table de correspondance, getattr devient beaucoup plus pertinent.

Ajouter une valeur par défaut pour éviter AttributeError

La forme la plus pratique accepte un troisième argument :

getattr(objet, "nom_attribut", valeur_par_defaut)

Si l’attribut existe, Python renvoie sa valeur. S’il est absent, la valeur par défaut est utilisée au lieu de lever une exception.

ville = getattr(utilisateur, "ville", "Ville inconnue")
print(ville)

Dans ce cas, l’objet ne possède pas forcément d’attribut ville, mais le programme continue avec Ville inconnue. Cette approche convient très bien aux données optionnelles et aux versions différentes d’une configuration.

Il faut cependant distinguer un attribut absent d’un attribut qui vaut déjà None. La valeur par défaut n’est utilisée que lorsque la recherche échoue.

class Profil:
    langue = None

profil = Profil()

print(getattr(profil, "langue", "français"))

Le résultat sera None, et non français, car l’attribut existe. C’est une nuance importante lorsque None représente une valeur volontaire. Si l’application doit traiter None comme une absence, il faut ajouter une vérification séparée.

Sans troisième argument, une faute de frappe comme getattr(utilisateur, "nmo") produit une AttributeError. Je préfère souvent laisser cette exception apparaître dans le code interne, car elle révèle immédiatement un bug, et réserver la valeur par défaut aux données réellement facultatives.

Schéma Python illustrant une classe

Lire des méthodes, des modules et des options dynamiques

getattr() ne se limite pas aux variables d’instance. Il peut aussi récupérer une méthode. Il suffit ensuite d’ajouter les parenthèses pour l’exécuter.

class Message:
    def envoyer(self):
        return "Message envoyé"

message = Message()
nom_methode = "envoyer"

methode = getattr(message, nom_methode)
print(methode())

Cette technique permet de choisir une action à partir d’un texte. Elle apparaît dans les systèmes de plugins, les routeurs simples, les commandes administratives ou les fonctions qui sélectionnent un traitement selon un type d’événement.

actions = {
    "creation": "creer",
    "suppression": "supprimer"
}

action = "creation"
nom_methode = actions[action]

getattr(service, nom_methode)()

Le dictionnaire rend ici la correspondance visible et contrôlable. Je déconseille en revanche d’exécuter directement n’importe quel nom reçu d’un utilisateur. Un nom d’attribut externe doit être comparé à une liste blanche, sinon le programme risque de donner accès à des méthodes qui n’étaient pas prévues.

La fonction fonctionne aussi avec des modules et des classes :

import math

nom_fonction = "sqrt"
racine = getattr(math, nom_fonction)

print(racine(81))

Ce mécanisme est utile lorsque le choix d’une fonction dépend d’un paramètre de configuration. Pour quelques options seulement, un dictionnaire de fonctions reste souvent plus lisible. Pour une architecture extensible, l’accès dynamique peut toutefois éviter une longue suite de conditions.

Choisir entre getattr, accès direct, hasattr et try except

Ces solutions répondent à des besoins proches, mais elles ne doivent pas être utilisées indifféremment. Le choix dépend surtout de la manière dont le nom de l’attribut est connu et de l’importance de l’erreur.

Solution Quand l’utiliser Point fort Limite
objet.nom Le nom est connu dans le code Très lisible Pas dynamique
getattr() Le nom arrive dans une variable Valeur par défaut intégrée Peut masquer une faute de frappe
hasattr() Il faut seulement tester l’existence Test court Ne renvoie pas la valeur
try/except L’absence est une situation exceptionnelle Gestion précise de l’erreur Plus verbeux

Un piège courant consiste à écrire hasattr(), puis à appeler immédiatement getattr(). Entre les deux opérations, une propriété peut produire un effet ou changer de valeur. Dans la plupart des cas, il est plus propre de récupérer directement l’attribut avec une valeur par défaut ou de gérer une seule exception.

try:
    valeur = getattr(objet, nom)
except AttributeError:
    valeur = valeur_par_defaut

Cette forme est intéressante lorsque l’absence doit être distinguée d’une autre erreur interne. À l’inverse, si l’on veut simplement afficher une option facultative, getattr(objet, nom, None) sera plus compact.

Éviter les erreurs fréquentes et les effets inattendus

Ne pas confondre une propriété avec une simple variable

La recherche d’attribut respecte le fonctionnement normal de Python. Elle peut donc déclencher une propriété définie avec @property, ou une logique personnalisée dans __getattribute__() et __getattr__().

class Compte:
    @property
    def solde(self):
        print("Calcul du solde")
        return 150

compte = Compte()
print(getattr(compte, "solde"))

L’appel affiche le message avant de renvoyer le montant. Cela signifie que getattr n’est pas toujours une lecture passive. Une propriété peut effectuer un calcul, consulter une ressource ou lever une exception particulière.

Protéger les noms venant de l’extérieur

Un nom d’attribut provenant d’une requête HTTP, d’un fichier ou d’une entrée utilisateur ne devrait pas être utilisé sans contrôle. Même si getattr() ne permet pas à lui seul d’exécuter du code arbitraire, il peut exposer des attributs internes ou des méthodes sensibles.

methodes_autorisees = {
    "resume": service.resume,
    "statut": service.statut
}

nom = "resume"
resultat = methodes_autorisees[nom]()

Cette version est plus sûre lorsqu’il existe peu d’actions possibles. Elle documente aussi clairement l’interface publique. Pour une application exposée sur Internet, je privilégie ce type de liste blanche explicite plutôt qu’un accès libre à tous les attributs.

Lire aussi : Python - Comment vérifier si un nombre est pair facilement ?

Surveiller les fautes de frappe et les performances

Une valeur par défaut peut rendre l’application trop silencieuse. Si "username" est écrit à la place de "user_name", le programme continuera peut-être avec une valeur vide et le problème apparaîtra beaucoup plus tard.

Pour quelques appels isolés, le coût de getattr() ne pose pas de problème. Dans une boucle très chaude exécutée des millions de fois, un accès direct ou une référence mise en cache sera généralement plus simple et légèrement plus rapide. La lisibilité du code doit rester le premier critère, car l’écart de performance est rarement décisif dans une application classique.

Utiliser getattr avec des classes bien conçues

Dans une classe, il est possible de définir __getattr__() pour fournir un comportement de secours lorsque l’attribut n’existe pas. Cette méthode ne doit pas être confondue avec la fonction intégrée getattr() utilisée par le code appelant.

class Parametres:
    def __init__(self):
        self.langue = "fr"

    def __getattr__(self, nom):
        return f"Option inconnue : {nom}"

parametres = Parametres()

print(getattr(parametres, "langue"))
print(getattr(parametres, "theme"))

Le premier appel renvoie fr. Le second déclenche __getattr__() et renvoie un message personnalisé. Ce modèle peut être utile pour des objets qui représentent une configuration flexible, mais je l’emploie avec retenue. Un attribut absent qui ressemble à une vraie faute de programmation ne devrait pas être transformé en résultat valide sans avertissement.

Pour les projets avec analyse statique et annotations de type, un accès dynamique est aussi moins facile à comprendre pour les outils comme les vérificateurs de types. Quand les attributs possibles sont connus à l’avance, une classe clairement annotée ou un dictionnaire typé offrira souvent une meilleure expérience de maintenance.

Le bon réflexe pour intégrer getattr dans un code fiable

La règle que je retiens est simple. Utilisez l’accès direct quand le nom est connu, getattr() quand le nom est réellement dynamique, et une valeur par défaut seulement lorsque l’absence est normale.

Pour un code robuste, vérifiez trois points avant de l’adopter : la source du nom, le comportement attendu si l’attribut manque et la possibilité qu’une propriété exécute une logique supplémentaire. Cette petite discipline évite la majorité des usages confus.

Bien employée, cette fonction devient un outil discret mais puissant pour les configurations, les extensions et les systèmes pilotés par des noms. Elle ne remplace pas une structure claire, mais elle permet à Python de rester flexible sans multiplier les conditions inutiles.

Questions fréquentes

Utilisez l’accès direct lorsque le nom de l’attribut est connu dans le code. getattr() devient pertinent lorsque ce nom provient d’une variable, d’une configuration, d’un formulaire ou d’une table de correspondance.
Ajoutez une valeur par défaut en troisième argument, par exemple getattr(utilisateur, "ville", "Ville inconnue"). Cette valeur est utilisée uniquement si l’attribut n’existe pas : si l’attribut existe mais vaut None, le résultat reste None.
hasattr() sert uniquement à tester l’existence, tandis que getattr() récupère la valeur et peut fournir une valeur par défaut. Utilisez try/except lorsque l’absence doit être distinguée d’une autre erreur interne ou traitée comme une situation exceptionnelle.
Récupérez la méthode avec getattr(objet, nom_methode), puis appelez le résultat avec des parenthèses. Si le nom vient de l’extérieur, contrôlez-le avec une liste blanche ou un dictionnaire d’actions autorisées afin de ne pas exposer des méthodes internes ou sensibles.
La recherche peut exécuter une propriété définie avec @property, ou invoquer une logique personnalisée dans __getattribute__() et __getattr__(). Une propriété peut donc effectuer un calcul, consulter une ressource ou lever une exception.
Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

plugins attributs méthodes propriétés configuration
Autor Denis Ribeiro
Denis Ribeiro
Je m'appelle Denis Ribeiro et j'ai quatre ans d'expérience dans le domaine de la technologie, en particulier dans les domaines du web, de l'intelligence artificielle, des réseaux et de la sécurité. Mon intérêt pour ces sujets a commencé dès mon plus jeune âge, lorsque j'ai découvert à quel point la technologie pouvait transformer notre quotidien. J'aime expliquer des concepts complexes de manière simple, afin d'aider mes lecteurs à mieux comprendre les enjeux actuels et futurs de notre monde numérique. Dans mes écrits, je m'efforce de fournir des informations utiles, précises et à jour. Je prends le temps de vérifier mes sources et de comparer les informations, tout en suivant les dernières tendances du secteur. Mon objectif est de rendre l'apprentissage accessible à tous, en organisant mes connaissances de manière claire et structurée, afin que chacun puisse naviguer avec confiance dans cet univers en constante évolution.
Commentaires (0)
Ajouter un commentaire