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 :

Multiple initialisation d'une classe [Python 3.X]


Sujet :

Python

  1. #1
    Membre actif Avatar de Masmeta
    Homme Profil pro
    Ing. R&D informatique industrielle
    Inscrit en
    Mai 2006
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Ing. R&D informatique industrielle
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 472
    Points : 221
    Points
    221
    Par défaut Multiple initialisation d'une classe
    Bonjour,

    J'ai créé une classe qui a besoin d'avoir plusieurs initialisation. Je ne sais pas comment implémenter cela.
    Naïvement j'ai fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class foo(object) : 
        def __init__(self, id, label, pointsList) :
            [...]  
        def __init__(self, id, label, centerPoint, width, height) :
            [...]
    Et cela ne fonctionne pas.
    J'ai vu le principe suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class foo(object) : 
        def __init__(self, *args,**kwargs) :
            [...]
    Je n'ai pas compris ce principe.

    Quel est la meilleur façon de faire pour pour avoir la possibilité d'avoir une initialisation multiple ?
    Je vous remercie pour votre aide.
    "Nulla Tenaci Invia Est Via"
    Aux persévérants aucune route n'est interdite

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par Masmeta Voir le message
    Quel est la meilleur façon de faire pour pour avoir la possibilité d'avoir une initialisation multiple ?
    Techniquement, on ne sait pas "surcharger" une méthode: il n'y aura qu'un seul __init__ (et si vous en définissez 2, le dernier écrase l'autre).
    Vous pouvez éventuellement écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def __init__(self, id, label, centerPoint, width=None, height=None)
    et trier (ou pas).
    Mais la vraie question est de savoir quel problème vous essayez de résoudre en voulant faire fonctionner cela.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre actif Avatar de Masmeta
    Homme Profil pro
    Ing. R&D informatique industrielle
    Inscrit en
    Mai 2006
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Ing. R&D informatique industrielle
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 472
    Points : 221
    Points
    221
    Par défaut
    Je désire générer un objet poly-line de différentes façon.
    Je suis parti sur le principe suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    class foo : 
        def __init__(self)
     
        def byListOfPoint(self,listOfPoint) :
            [..]
     
        def byCenterPoint(self,centerPoint, width,height) :
            [..]
    obj = foo()
    obj.byListOfPoint(mylistOfPoint)
    obj1 = foo()
    obj1.byCenterPoint((10,10),W,H)
    "Nulla Tenaci Invia Est Via"
    Aux persévérants aucune route n'est interdite

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par Masmeta Voir le message
    Je désire générer un objet poly-line de différentes façon.
    Utiliser des class method répondrait bien à çà:
    Code : 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 foo : 
        def __init__(self, #...les arguments de base):
             ....
        @classmethod
        def from_list(cls, alist) :
             ...
             return cls(....)
     
        @classmethod
        def from_center(cls, centerPoint, width,height) :
            ...
            return cls(....)
     
    obj1 = Foo.from_list(mylistOfPoint)
    obj2 = Foo.from_center((10,10),W,H)
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre actif Avatar de Masmeta
    Homme Profil pro
    Ing. R&D informatique industrielle
    Inscrit en
    Mai 2006
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Ing. R&D informatique industrielle
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 472
    Points : 221
    Points
    221
    Par défaut
    J'ai lu ce type de code plusieurs fois. Et j'avoue ne pas avoir bien compris.

    Et pourquoi une méthode de classe réponds mieux qu'une méthode d'instance?
    "Nulla Tenaci Invia Est Via"
    Aux persévérants aucune route n'est interdite

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Masmeta Voir le message
    J'ai lu ce type de code plusieurs fois. Et j'avoue ne pas avoir bien compris.

    Et pourquoi une méthode de classe réponds mieux qu'une méthode d'instance?
    Pour autant que çà fonctionne, on fait ce qu'on veut.

    Après vous avez des arguments "non-fonctionnels", par exemple, qu'est ce qu'on met dans __init__? l'initialisation des attributs de l'instance à partir des arguments reçus.
    Ce qui évite d'avoir un __init__ qui fabrique une instance bancale en attendant que l'utilisateur appelle une des méthodes qui fera le boulot (il peut oublier).
    De plus comme il y en a plusieurs, çà ne va pas être coton d'assurer la cohérence des différents points d'entrées quant aux attributs crées.

    D'où l'intérêt d'avoir un "vrai" __init__ qui force la définition d'une interface de ce qu'il faut passer pour créer une instance.... et des méthodes de classe qui se contentent de récupérer les arguments pour les mettre en forme, les passer au constructeur,... et retourner l'instance créée.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Masmeta Voir le message
    J'ai vu le principe suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    class foo(object) : 
        def __init__(self, *args,**kwargs) :
            [...]
    Je n'ai pas compris ce principe.
    Bonjour

    Ca permet d'appeler une fonction/méthode avec des paramètres pas forcément attendus (on va pas dire "facultatifs" parce que ce type se résoud avec des valeurs par défaut) mais c'est carrément un truc style "si le paramètre y est je le récupère et s'il n'y est pas je m'en balance". La fonction/méthode rangera alors les paramètres non nommés dans le tuple "args" et les paramètres nommés dans le dictionnaire "kwargs".

    Exemple
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def fct(nom, *args, **kwargs):
    	print("nom=", nom)
    	print("args=", args)
    	print("kwargs=", kwargs)
    # fct()
     
    fct("César", "Julius", "Caius", grade="général", victoire="Alésia", défaite="Gergovie")

    Le premier paramètre "César" sera stocké dans l'argument "nom" prévu à cet effet. Ensuite les paramètres non nommés seront stockés dans le tuple "args" qui contiendra alors ("Julius", "Caius"). Et les paramètres nommés seront stockés dans le dictionnaire "kwargs" qui contiendra alors {"victoire" : "Alésia", "défaite" : "Gergovie"}.

    A partir de là, pas compliqué de programmer un traitement qui gère en fonction...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def fct(nom, *args, **kwargs):
    	if "victoire" in kwargs.keys():
    		... (faire un truc spécial avec kwargs["victoire"])...
    	if "défaite" in kwargs.keys():
    		... (faire un truc spécial avec kwargs["défaite"])...
    	... (suite classique)
    # fct()

    Moi je m'en sers surtout pour activer des trucs style debug ou log (ex fct(..., ..., debug=True, log="/tmp/trace.log"). Effectivement cette technologie s'appliquerait aussi pas mal à ton problème...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class foo(object) : 
    	def __init__(id, label, **kwargs):
    		self.__pointsList=kwargs.get("pointsList", None)
    		self.__centerPoint=kwargs.get("centerPoint", None)
    		self.__with=kwargs.get("with", None)
    		self.__height=kwargs.get("height", None)
    	# __init__()
    # class foo()
    foo(100, "rectangle", centerPoint=(10, 10), width=100, height=500)
    foo(200, "carre", pointsList=((0, 0), (0, 100), (100, 100), (100, 0)))
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre actif
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2018
    Messages
    73
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Mai 2018
    Messages : 73
    Points : 228
    Points
    228
    Par défaut
    Citation Envoyé par Masmeta Voir le message
    J'ai lu ce type de code plusieurs fois. Et j'avoue ne pas avoir bien compris.

    Et pourquoi une méthode de classe réponds mieux qu'une méthode d'instance?
    Parce que vous voulez instancier un objet, donc à partir d'une classe.

    Et là il faut comprendre 3 choses :
    - On crée une instance à partir d'une classe
    - la succession des appels __new__ et __init__ est la procédure pour instancier une classe en Python
    - __init__ est une méthode d'instance appelée pour initialiser un objet après qu'il ai été créé.

    Comme il a été répondu, il n'y a pas de surcharge horizontale en Python on ne surcharge donc pas la méthode __init__ afin d'exposer plusieurs signatures.

    Comme l'a exposé Wiztricks, un objet doit être cohérent après avoir été instancié. Vous ne devez déléguer aucune connaissance technique de votre implémentation à vos utilisateurs de l'objet (ce serait une violation du principe de l'encapsulation).

    Le principe est donc de modéliser votre classe et de définir comment les objets seront initialisés. L'exercice est difficile car il nécessite que vous fassiez abstraction de votre "besoin" afin d'avoir le design le plus "neutre" possible. Ensuite, il vous faut définir vos alternatives et définir les constructeurs adéquats. Vous avez de beaux exemples avec la classe datetime qui propose les constructeurs today(), now(), fromtimestamp(), fromisoformat()…
    Ces méthodes de classe auront leur logique spécifique de traitement des paramètres et appelleront le constructeur de votre classe afin de retourner l'objet instancié.

    Mais pour répondre encore plus précisément à votre question, regardez la signature de ces méthodes. Le premier paramètre n'est pas self mais cls. Ceci est fondamental pour ne pas avoir de problème avec une autre notion fondamentale de la POO : l'héritage. Si je spécialise votre classe, je dois avoir un comportement cohérent. Imaginez que je veuille créer un objet ClosedPolyline qui "ferme" le poliligne en ajoutant une dernière coordonnée qui est égale à la première. Il me suffira de surcharger le constructeur (on peut surcharger verticalement) et je n'ai pas à toucher aux autres constructeurs.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Get Set de multiples variables dans une classe
    Par lupus5 dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 30/05/2016, 07h41
  2. initialisation d'une classe
    Par stracoma dans le forum C++
    Réponses: 4
    Dernier message: 02/04/2015, 16h57
  3. Probleme d'initialisation dans une classe
    Par AirSounet dans le forum Débuter
    Réponses: 5
    Dernier message: 27/06/2011, 16h50
  4. Réponses: 4
    Dernier message: 20/01/2011, 10h49
  5. [Debutant] Initialisation d'une classe
    Par etiennegaloup dans le forum Débuter
    Réponses: 5
    Dernier message: 09/01/2006, 22h12

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