IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Comment ajouter une méthode à un objet, qui n'existe pas dans sa classe ?


Sujet :

Python

  1. #1
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mai 2023
    Messages
    211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mai 2023
    Messages : 211
    Par défaut Comment ajouter une méthode à un objet, qui n'existe pas dans sa classe ?
    Salut !

    En python je sais rajouter des attributs à un objet qu'il n'a pas dans sa classe, mais je sais pas faire pour les méthodes.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 593
    Par défaut
    Bonsoir,
    Dans tous les cas, au moins en Python 3, tu peux assigner un attribut à une classe ou à une instance de classe, soit directement, soit à l'aide de setattr()
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    target.attribut = valeur
    setattr(target, "attribut", valeur)

    Mais si tu en arrives là, c'est qu'il y a probablement une erreur de conception dans ton approche et c'est elle qu'il faut corriger avant d'aller plus loin, à commencer pour éviter de prendre de mauvaises habitudes dès le départ. Cela dit, il y a trois manières de faire :

    1. Ajouter un attribut lambda à une instance de classe

    Tu peux ajouter une fonction lambda en tant qu'attribut d'instance. Mais comme celle-ci n'appartiendra qu'à cette instance et donc pas aux autres objets du même type, elle se comportera comme une fonction ordinaire et ne recevra pas le paramètre self. Elle ne pourra donc pas accéder aux autres attributs de l'instance de ta classe :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MaClasse:
        def MethodeUne(self):
            print("Méthode une -", self)
     
    ma_classe = MaClasse()
    setattr(ma_classe, "MethodeDeux", lambda self: print("Methode deux -", self)) # via setattr()
    ma_classe.MethodeDeux =           lambda self: print("Methode deux -", self)  # par assignation directe
     
    ma_classe.MethodeUne()       # Methode une - <__main__.MaClasse object at 0x7fc2c8691400>
    ma_classe.MethodeDeux()      # Ne fonctionnera pas
    ma_classe.MethodeDeux(None)  # Methode deux - None

    2. Ajouter un attribut lambda à la définition de la classe

    Il est possible d'intervenir directement sur l'objet global servant de prototype de classe et à instancier les autres. Cependant, cela revient en fait à redéfinir la classe. Les méthodes que tu vas ajouter seront considérées comme en faisant partie et recevront donc le paramètre self. En revanche, elles vont devenir communes à toutes les instances de ta classe, y compris celles qui sont apparues avant que tu effectues ces modifications.

    Dans l'exemple suivant, on déclare une première instance a et on essaie d'appeler les deux méthodes. La première fonctionne mais la seconde n'existe pas encore. Par la suite, on instancie b puis on modifie la définition de la classe pour lui ajouter une méthode. On s'aperçoit alors qu'il est devenu possible d'appeler MethodeDeux() aussi depuis a que b :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class MonAutreClasse:
        def MethodeUne(self):
            print("Méthode une -", self)
     
    a = MonAutreClasse()
    a.MethodeUne()     # Méthode une - <__main__.MonAutreClasse object at 0x7f4a10195400>
    a.MethodeDeux()    # Ne fonctionnera pas
     
    b = MonAutreClasse()
     
    setattr(MonAutreClasse, "MethodeDeux", lambda self: print("Methode deux -", self)) # via setattr()
    MonAutreClasse.MethodeDeux =           lambda self: print("Methode deux -", self)  # par assignation directe
     
    a.MethodeUne()     # Méthode une - <__main__.MonAutreClasse object at 0x7f4a10195400>
    a.MethodeDeux()    # Methode deux - <__main__.MonAutreClasse object at 0x7f4a10195400>
     
    b.MethodeUne()     # Méthode une - <__main__.MonAutreClasse object at 0x7f4a1017ce10>
    b.MethodeDeux()    # Methode deux - <__main__.MonAutreClasse object at 0x7f4a1017ce10>

    3. Dériver la classe

    La dérivation de classe est la vraie voie à suivre, c'est un des piliers de la programmation orientée objet et c'est même la seule que te laisseront suivre certains langages. Les approches ci-dessus ne fonctionneront que si le langage est permissif et interprété (c'est utilisable en Javascript par exemple) mais pas avec du typage fort ni si le langage est compilé. Typiquement : elles ne fonctionneront pas en C++.

    Dans l'exemple suivant, on définit non pas une mais deux classes. Une première classe « A » et une seconde classe « B » qui dérive de A. Donc, de la même façon qu'un « ChatAngora » est implicitement un « Chat », notre classe B sera implicitement une A dotée d'éléments supplémentaires. Les objets de type B pourront être passés partout où l'on attend un type A, mais l'inverse ne sera pas vraie.

    C'est d'ailleurs là l'origine du mot « classe », qui doit en fait se comprendre comme « classification du règne animal », par exemple.

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class A:
        def MethodeUne(self):
            print("Méthode une -", self)
     
    class B(A):
        def MethodeDeux(self):
            print("Méthode deux -", self)
     
    a = A()
    b = B()
     
    a.MethodeUne()     # Méthode une - <__main__.A object at 0x7f7d5c091550>
    a.MethodeDeux()    # Ne fonctionnera pas
     
    b.MethodeUne()     # Méthode une - <__main__.B object at 0x7f7d5c091400>
    b.MethodeDeux()    # Méthode deux - <__main__.B object at 0x7f7d5c091400>

  3. #3
    Membre confirmé
    Homme Profil pro
    sans
    Inscrit en
    Mai 2023
    Messages
    211
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : sans

    Informations forums :
    Inscription : Mai 2023
    Messages : 211
    Par défaut
    Merci beaucoup pour ta réponse qui est approfondie et j'ai bien appris grace à cela.

    Ce que j'ai fait en fait c'est une classe de vaisseaux, qui est dérivée d'une classe principale, et de cette classe dérivée, je tire deux instances, mais la deuxième instance doit avoir une méthode que la première instance n'a pas, c'est à dire que la méthode nouvelle n'est pas dans la classe dérivée.
    j'espère que je suis assez clair, lol

    Je veux faire ça car le premier des deux vaisseaux de la classe dérivée, tire un missile.
    Tandis que le deuxième tire deux boulets en même temps (un à gauche et un à droite) et pour ça j'ai besoin que ce deuxième vaisseau ait sa propre méthode donc.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 755
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 755
    Par défaut
    Peut-être regarder du côté des méthodes abstraites (https://www.docstring.fr/glossaire/classe-abstraite/)
    ou alors tu rajoutes une couche d'héritage par catégorie de vaisseaux
    parce que tes 2 vaisseaux tirent, mais pas de la même façon (même fonction mais pas même contenu, donc éventuellement paramètre/objet différent passé à la fonction)

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 593
    Par défaut
    Citation Envoyé par nouby Voir le message
    Je veux faire ça car le premier des deux vaisseaux de la classe dérivée, tire un missile.
    Tandis que le deuxième tire deux boulets en même temps (un à gauche et un à droite) et pour ça j'ai besoin que ce deuxième vaisseau ait sa propre méthode donc.
    D'accord, tu es donc en train d'écrire un shoot'em up.

    Ce que j'ai fait en fait c'est une classe de vaisseaux, qui est dérivée d'une classe principale, et de cette classe dérivée, je tire deux instances, mais la deuxième instance doit avoir une méthode que la première instance n'a pas, c'est à dire que la méthode nouvelle n'est pas dans la classe dérivée.
    En théorie, cela signifierait donc que la deuxième instance est elle-même une classe dérivée de la classe dérivée. Rien ne t'empêche de dériver les classes à l'infini, mais il faut se souvenir qu'il s'agit à chaque fois d'un nouveau type, donc il vaut mieux le faire lorsque c'est réellement nécessaire. Cela dit, tu obtiendrais le diagramme suivant :

    Code Texte : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                                        +--- Vaisseau lance-missile
                                        |
      ClassePrincipale <--- Vaisseau <--+
                                        |
                                        +--- Vaisseau lance-boulets

    En réalité, l'approche la plus intelligente ici consiste en fait à déclarer des classes pour les armes en particulier :

    Code Texte : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
              +--- Lance-missile
              |
      Arme <--+
              |
              +--- Lance-boulets

    … et de prévoir un champ « arme » dans la classe « Vaisseau » :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class Vaisseau:
        arme = None

  6. #6
    Rédacteur/Modérateur


    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 713
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 713
    Billets dans le blog
    67
    Par défaut
    Bonjour à tous,

    En complément, si je reprends votre première discussion et votre méthode tirer(), j'y vois un argument arme et donc vous sembler vouloir gérer ce cas au niveau de cette méthode tirer() ?

    Après il faut voir bien sûr si ça peut se gérer uniquement à ce niveau là, peut-être en définissant le type de tire à l'aide d'un attribut type_tire au moment de la création de l'objet. Et sinon les propositions qui ont été faites me semblent aussi valables.

    Cdlt
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

Discussions similaires

  1. Réponses: 3
    Dernier message: 13/12/2023, 08h39
  2. Problème d'objet qui n'existe pas dans la session
    Par informatica1989 dans le forum Struts 2
    Réponses: 0
    Dernier message: 28/12/2011, 15h16
  3. Réponses: 1
    Dernier message: 03/02/2010, 15h54
  4. Réponses: 4
    Dernier message: 22/07/2009, 11h52
  5. Réponses: 2
    Dernier message: 06/07/2006, 13h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo