CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[Python] avoir le nom d'instanciation d'un objet

Spryfoudre
Spryfoudre
Niveau 8
28 mars 2021 à 16:41:26

Bonjour,

Je dois faire un script qui reçoit plusieurs objets d'une classe dont je dois me servir, mais je ne sais pas à l'avance sous quels noms ils seront définis. J'arrive à avoir l'id au moment de l'initiation (id(self), mais je sais pas si c'est possible d'arriver au nom avec :(
Si vous connaissez un moyen, quelque chose comme name(self) ou je ne sais pas quoi, j'arrive pas à trouver ce que je cherche sur internet :hap:

( Au cas où je précise, je veux pas un attribut nom :hap:)

Spryfoudre
Spryfoudre
Niveau 8
28 mars 2021 à 16:47:35

Contexte si ça peut aider:

J'ai:

class eleve:
def __init__:
self.nom = nom
self.taille = taille
.....

et je reçois:

Kev = eleve()
Kev.nom = Kevin
Kev.taille = ...

Comment savoir que l'objet s'appelle Kev ? :hap:

Azerban
Azerban
Niveau 16
28 mars 2021 à 17:40:35

Il n'y a pas vraiment de méthode pour faire cela, en Python les variables ne sont que des conteneurs qui stockent des adresses vers des objets (des pointeurs).

Mais si tu veux connaître les variables qui référencent des objets qui sont des instances d'une classe précise tu peux faire un truc comme ça :

class Eleve:
    def __init__(self, name):
        self.name = name

tit = Eleve("Titouan")
cor = Eleve("Corentin")

class_ = Eleve

eleves = [v_name for v_name, value in locals().items() if isinstance(value, class_) if not v_name.startswith("_")]

print(eleves)

Retourne :

['tit', 'cor']

Attention, si ta variable commence par un underscore, elle ne sera pas stockée dans la liste.

Spryfoudre
Spryfoudre
Niveau 8
28 mars 2021 à 17:47:07

Merci, ça fait le travail, même si c'est un peu tarabiscoté :hap:
Y'aurait pas quelque chose de plus simple à glisser dans le __init__ pour ajouter le nom dans un tableau et l'utiliser après ? :(

Sinon je comprend pas l'intérêt de "if not v_name.startswith("_")" :question:

Azerban
Azerban
Niveau 16
28 mars 2021 à 18:33:26

Ce que tu peux faire, c'est écrire une méthode de classe dans ta classe Eleve qui renvoie la résultat escompté. Ensuite tu peux appeler la méthode depuis ta classe ou une instance :

class Eleve:
    def __init__(self, name):
        self.name = name
    
    @classmethod
    def get_instance_name(cls):
        return [v_name for v_name, value in globals().items() if isinstance(value, cls)]

On créé des instances :

cor = Eleve("Corentin")
tit = Eleve("Titouan")

Tu peux ensuite appeler ta méthode depuis les instances ou la classe :

cor.get_instance_name()
tit.get_instance_name()

Eleve.get_instance_name()
['tit', 'cor']

Le startswith c'est parce que Python créé également des instance de Eleve pour son cache (du genre _15).

Si tu tapes globals(), tu verras un dictionnaire qui contient toutes les variables créées par toi-même et la machine virtuelle de Python.

Azerban
Azerban
Niveau 16
28 mars 2021 à 18:53:03

D'ailleurs, tu n'as pas besoin de classmethod si tu désires appeler la méthode uniquement depuis les instances, dans ce cas tu peux utiliser le décorateur property pour décorer ta méthode et appeler la méthode à la manière d'un attribut (sans les parenthèses) :

class Eleve:
    def __init__(self, name):
        self.name = name
    
    @property
    def instances(self):
        return [v_name for v_name, value in globals().items() if isinstance(value, self.__class__)]

cor = Eleve("Corentin")
tit = Eleve("Titouan")
ale = Eleve("Alexandre")

print(cor.instances)

Retourne :

['cor', 'tit', 'ale']
Spryfoudre
Spryfoudre
Niveau 8
28 mars 2021 à 18:56:53

Oui je comprend l'idée, plutôt malin, merci :hap:
En revanche je peux pas utiliser les variables dans le tableau vu qu'elles sont stockés comme des strings :(

C'est sûrement moi qui cherche à faire quelque chose d'impossible en fait vu qu'il y a pas de pointeurs en python, est-ce qu'il y aurait plutôt une solution pour itérer tous les objets d'une classe ? :(

Une sorte de:

for i in "liste de tous les objets de la classe Eleve":
print (i.taille)
print (i.nom)

Je sais pas si c'est clair :hap:

Azerban
Azerban
Niveau 16
28 mars 2021 à 19:06:00

Tu peux utiliser eval.

En reprenant l'exemple avec classmethod (plus pythonique je trouve) :

class Eleve:
    def __init__(self, name):
        self.name = name
    
    @classmethod
    def instances(cls):
        return [v_name for v_name, value in globals().items() if isinstance(value, cls)]

cor = Eleve("Corentin")
tit = Eleve("Titouan")
ale = Eleve("Alexandre")

for obj in Eleve.instances():
    print(eval(obj).name)

Retourne :

Corentin
Titouan
Alexandre
Spryfoudre
Spryfoudre
Niveau 8
28 mars 2021 à 19:13:30

Ça marche ! :)

J'avais vu nul part ce eval(), je comprend pas pourquoi :(

Merci beaucoup du temps que tu m'as accordé mec, t'es un chef :)

Azerban
Azerban
Niveau 16
28 mars 2021 à 19:17:11

Je t'avoue que je ne comprend pas trop ce que tu veux faire exactement, j'ai l'impression que tu veux juste créer des instances et ensuite parcourir tes instances. Si tu n'as pas besoin du nom de variable de tes instances, tu peux faire ça extrêmement facilement avec un attribut de classe :

class Eleve:
    instances = []

    def __init__(self, name):
        self.name = name
        self.__class__.instances.append(self)

cor = Eleve("Corentin")
tit = Eleve("Titouan")
ale = Eleve("Alexandre")

for obj in Eleve.instances:
    print(obj.name)
Message édité le 28 mars 2021 à 19:18:36 par Azerban
Spryfoudre
Spryfoudre
Niveau 8
28 mars 2021 à 19:30:10

Le prof doit entrer plusieurs fonctions, les répertorier dans une classe et après je dois les trier pour dire lesquelles on doit exécuter avant lesquelles :hap:

Il veut quand même le nom des objets qu'il fait je crois... donc je vais garder la première méthode, même si la deuxième est bien + simple et intuitive :hap:

Il entre les informations pour créer l'objet, mais après je dois y accéder aux attributs dans une autre classe, mais je sais pas à l'avance ce qu'il aura comme fonction. Je m'y prends sûrement pas de la façon optimale mais bon... :hap:

Si tu veux en savoir + https://docdro.id/mAJOuAF

Message édité le 28 mars 2021 à 19:33:59 par Spryfoudre
Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Internet
  • Macintosh
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment