Acceder à un attribut de classe par un variable

mortel -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -

Bonjour,

debutant sur python 3.11.2

supposons que j'ai ce code ci-dessous

class Point:
    pointx = 3
    pointy = 7
    pointZOZO = "khkhkhkh"


p = Point()
p.pointx = 9
print("p : x =", p.pointx, "y =", p.pointy)

et il possible d'acceder à pointx et pointy au travers une variable ?

class Point:
    pointx = 3
    pointy = 7
    pointZOZO = "khkhkhkh"


p = Point()
Var = "pointx"

#un truc du genre
p.Var = 9

print("p : x =", p.pointx, "y =", p.pointy)

Merci de vos lumieres
Windows / Firefox 102.0

4 réponses

  1. PierrotLeFou
     

    Ceci t'aide-t-il?

    class toto:
       tata = 3
    t = toto()
    t.tata =0
    print(t.tata)

    0
  2. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     

    Bonjour,

    Dans Var = 'pointx', Var est une variable, un contenant, et 'pointx' est une chaine de caractères contenue

    dans Var

    En écrivant p.Var = 9, tu ne modifie pas l'attribut pointx de la classe, tu ajoutes juste un attribut

    nommé Var et tu lui donnes la valeur 9

    De plus quel est l'intérêt de ce truc ?

    Tu devrais utiliser le constructeur __init__()  et accéder aux attributs de cette façon:

    class Point:
    
        def __init__(self,x = 0.0,y = 0.0,z=0.0):
            self.x = x
            self.y = y
            self.z = z
    
    p1 = Point(10.3, 5.2, 7.8)
    print(p1.x)
    0
  3. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     

    bonjour,

    C'est possible, et je ne pense pas que ce soit une bonne idée.  Pourquoi veux-tu faire cela?

    class Point:
        pointx = 3
        pointy = 7
        pointZOZO = "khkhkhkh"
    
    
    p = Point()
    Var = "pointx"
    
    #un truc du genre
    # p.Var = 9
    setattr(p, Var, 9)
    print("p : x =", p.pointx, "y =", p.pointy)
    
    0
  4. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     

    Bonjour,

    Il y a vraisemblablement confusion entre attribut de classe (attaché au type et partagé par toutes ses instances) et attribut d'instance (attaché à une instance de ce type). Ici, les coordonnées d'un point sont propres à une instance de point, et donc elles ne doivent pas être en attribut de classe mais bien en attribut d'instance.

    class Point:
        xmin = 0
        xmax = 1000
        ymin = 0
        ymax = 1000
    
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        def __repr__(self):
            return f"Point<{self.x}, {self.y}>"
    
    p1 = Point(1, 11)
    print(p1)  # Point<1, 11>

    Dans l'exemple ci-dessus :

    • xmin, xmax, ymin, ymax sont communes à tous les Points ;
      • on y accède normalement via le nom de la classe
        print(Point.xmin, Point.xmax, Point.ymin, Point.ymax)  # OK
      • ... et on peut y accéder via une instance de cette classe (même si l'instance en elle-même n'a aucune utilité, seul son type importe)
        p1 = Point(1, 11)
        print(p1.xmin, p1.xmax, p1.ymin, p1.ymax)  # OK, mais bof
    • x et y sont spécifique à chaque instance de Point. On ne peut que y accéder au travers d'une instance (pas au travers dy type)
      print(p1.x, p1.y)        # OK
      print(Point.x, Point.y)  # Faux: x et y ne sont pas des attributs de classe

    Ensuite tu peux parfaitement combiner des instructions mettant en jeu des attributs de classe et d'instance :

    class Point:
        xmin = 0
        xmax = 1000
        ymin = 0
        ymax = 1000
    
        def __init__(self, x, y):
            if not (Point.xmin <= x < Point.xmax):
                raise ValueError(f"Invalid x: {Point.xmin} <= {x} < {Point.xmax}")
            if not (Point.ymin <= y < Point.ymax):
                raise ValueError(f"Invalid y: {Point.ymin} <= {y} < {Point.ymax}")
            self.x = x
            self.y = y
    
        def __repr__(self):
            return f"Point<{self.x}, {self.y}>"
    
    p1 = Point(1, 11)   # OK
    p2 = Point(-2, 22)  # ValueError: Invalid x: 0 <= -2 < 1000

    Bonne chance

    0