Aller au contenu

Accéder aux attributs par leur nom

getattr() : lire un attribut

class Product:
    name = "Clavier"

product = Product()
print(getattr(product, "name"))                # Clavier
print(getattr(product, "price", 0))            # 0

Sans valeur de remplacement, un attribut absent provoque AttributeError.

Equivalent en C#

var product = new { Name = "Clavier" };
var property = product.GetType().GetProperty("Name");
object? value = property?.GetValue(product);
Console.WriteLine(value); // Clavier

GetProperty() et GetValue() permettent un accès réfléchi. Le code illustré traite une propriété publique ; les champs exigent GetField(). L’absence de propriété et une valeur null doivent être distinguées si le besoin l’exige.

hasattr() : tester la présence d'un attribut

class Product:
    name = "Clavier"

print(hasattr(Product(), "name"))   # True
print(hasattr(Product(), "price"))  # False

Le test tente réellement l'accès à l'attribut. Une propriété peut donc être exécutée. hasattr() renvoie False si cet accès lève AttributeError ; les autres exceptions se propagent.

Equivalent en C#

var product = new { Name = "Clavier" };
bool hasName = product.GetType().GetProperty("Name") is not null;
Console.WriteLine(hasName); // True

Ce contrôle réfléchit les métadonnées et n’exécute pas le getter. hasattr() tente réellement l’accès Python et peut donc exécuter une propriété : la similitude du besoin masque une différence de comportement.

setattr() : affecter un attribut

class Product:
    pass

product = Product()
setattr(product, "name", "Clavier")
print(product.name)  # Clavier

L'opération correspond ici à product.name = "Clavier". Tous les objets n'autorisent pas l'ajout ou la modification d'attributs.

Equivalent en C#

dynamic product = new ExpandoObject();
product.Name = "Clavier";
var attributes = (IDictionary<string, object?>)product;
attributes["Price"] = 69.90;
Console.WriteLine(product.Price);

Pour une propriété CLR existante et accessible en écriture, PropertyInfo.SetValue() convient. Ajouter librement un membre à un objet ordinaire n’est pas possible ; ExpandoObject fournit un modèle dynamique adapté. Le dictionnaire permet ici un nom déterminé à l’exécution.

delattr() : supprimer un attribut

class Product:
    pass

product = Product()
product.name = "Clavier"
delattr(product, "name")
print(hasattr(product, "name"))  # False

L'opération correspond ici à del product.name. Un attribut absent ou non supprimable peut provoquer une exception.

Equivalent en C#

dynamic product = new ExpandoObject();
product.Name = "Clavier";
var attributes = (IDictionary<string, object?>)product;
attributes.Remove("Name");
Console.WriteLine(attributes.ContainsKey("Name")); // False

Une propriété déclarée d’une classe CLR ne peut pas être supprimée d’une instance. Le rapprochement présenté concerne les membres dynamiques d’un ExpandoObject. Affecter null à une propriété ne la supprime pas.