Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 14 sur 14
  1. #1
    Invité de passage
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : avril 2011
    Messages : 17
    Points : 0
    Points
    0

    Par défaut Compréhension création de classe

    Comment comprendre la différence entre ceci
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #-*- coding: iso-8859-15 -*-
     
    class personne:
        def __init__(self,nom):
            self.nom=nom
            self.dico={}
            self.dico['cree']=nom
        def fiche(self):
            print ('mon nom est: %s et d=%s') % (self.nom,self.dico)
    e={}
     
    e[0]=personne('alice')
    e[0].dico['zero']='zero'
    e[0].fiche()
    e[1]=personne('bernard')
    e[1].dico['un']='un'
    e[1].fiche()
    e[0].fiche()
    Code :
    1
    2
    3
    mon nom est: alice et d={'zero': 'zero', 'cree': 'alice'}
    mon nom est: bernard et d={'un': 'un', 'cree': 'bernard'}
    mon nom est: alice et d={'zero': 'zero', 'cree': 'alice'}
    qui donne bien un dico par personne et cela

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #-*- coding: iso-8859-15 -*-
     
    class personne:
        nom=''
        dico={}
        def __init__(self,nom):
            self.nom=nom
            self.dico['cree']=nom
        def fiche(self):
            print ('mon nom est: %s et d=%s') % (self.nom,self.dico)
    e={}
     
    e[0]=personne('alice')
    e[0].dico['zero']='zero'
    e[0].fiche()
    e[1]=personne('bernard')
    e[1].dico['un']='un'
    e[1].fiche()
    e[0].fiche()
    Code :
    1
    2
    3
    mon nom est: alice et d={'zero': 'zero', 'cree': 'alice'}
    mon nom est: bernard et d={'zero': 'zero', 'un': 'un', 'cree': 'bernard'}
    mon nom est: alice et d={'zero': 'zero', 'un': 'un', 'cree': 'bernard'}
    qui crée un dico commun pour les personnes et un nom différent?

    Merci d'apporter de la lumière à ma compréhension du fonctionnement de Python

  2. #2
    Modérateur
    Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    janvier 2009
    Messages
    601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : janvier 2009
    Messages : 601
    Points : 965
    Points
    965

    Par défaut

    Houlà : ton exemple est bien compliqué !

    Plus simplement :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    >>> class Classe(object):
    ...     c = 0
    ...
    >>> Classe.c
    0
    >>> 
    >>> Classe.__dict__
    dict_proxy({'__dict__': <attribute '__dict__' of 'Classe' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Classe' objects>, 'c': 0, '__doc__': None})
    >>>
    >>> obj1 = Classe()
    >>> obj2 = Classe()
    >>> 
    >>> obj1.__dict__
    {}
    >>> 
    >>> obj1.c = "je la joue perso"
    >>> 
    >>> obj1.__dict__
    {'c': 'je la joue perso'}
    >>> 
    >>> obj1.c
    'je la joue perso'
    >>> Classe.c
    0
    >>> obj2.c
    0
    >>> obj2.__dict__
    {}
    c est, à la base, un attribut de classe, commun à toutes les instances. On ne le retrouve pas dans les attributs propres à une instance (lignes 13 et 14), seulement dans les attributs de la classe (lignes 7 et 8).

    Si une instance décide de se particulariser et de la "jouer perso", un attribut qui lui est propre est créé (lignes 16 à 19). Les autres instances n'auront toujours pas d'attribut "c" propre (lignes 25 à 28).

    Je n'ai pas (re)trouvé dans la doc officielle ce "truc". Mais, pour faire court, "c'est comme ça", faut faire avec.

  3. #3
    Invité de passage
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : avril 2011
    Messages : 17
    Points : 0
    Points
    0

    Par défaut

    Merci pour la réponse.
    C'est limpide, je comprends...

    Bonnes fêtes!

  4. #4
    Modérateur
    Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    janvier 2009
    Messages
    601
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : janvier 2009
    Messages : 601
    Points : 965
    Points
    965

    Par défaut

    Avec plaisir. Bonnes fêtes à toi aussi !

  5. #5
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    Bonjour,

    Citation Envoyé par plxpy Voir le message
    Je n'ai pas (re)trouvé dans la doc officielle ce "truc". Mais, pour faire court, "c'est comme ça", faut faire avec.
    C'est vrais qu'une explication manque sur le fonctionnement interne de la machine.

    Le comportement étant trop proche des paramètres par défaut pour les fonctions il m'est difficile de ne pas faire le parallèle.
    Pour rappel sur les paramètres par défaut, la doc officielle étant succincte (The default values are evaluated at the point of function definition in the defining scope).
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    >>> def f(l=[]):
    ...     l.append(0)
    ...     return l
    ... 
    >>> f()
    [0]
    >>> f()
    [0, 0]
    >>> f()
    [0, 0, 0]
    >>> id(f())
    3074972876L
    >>> id(f())
    3074972876L
    >>> id(f())
    3074972876L
    >>> f()
    [0, 0, 0, 0, 0, 0, 0]
    Nous avons bien ici le même objet (la fonction f, id 3074972876L), l'utilisation de la méthode se fait donc sur la même liste.

    Pour les instances cela vas de même
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> class Foo:
    ...     value = 0
    ... 
    >>> f = Foo()
    >>> f.__class__
    <class __main__.Foo at 0xb7745c8c>
    >>> f1 = Foo()
    >>> f1.__class__
    <class __main__.Foo at 0xb7745c8c>
    On utilise donc bien le même objet bien que les instances soit différentes.
    Code :
    1
    2
    3
    4
    >>> f
    <__main__.Foo instance at 0xb7485e8c>
    >>> f1
    <__main__.Foo instance at 0xb7485c6c>
    Pour ce qui est de 'la jouer perso' la résolution de l'attribut commence par l'espace de nom de l'instance.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    >>> class Foo(object):
    ...     classattr = "class"
    ... 
    >>> f = Foo()
    >>> f.classattr
    'class'
    >>> id(f.classattr)
    3077724160L
    >>> f.__class__.classattr
    'class'
    >>> id(f.__class__.classattr)
    3077724160L
    >>> f.classattr = "instance"
    >>> f.__dict__
    {'classattr': 'instance'}
    >>> f.classattr
    'instance'
    >>> id(f.classattr)
    3077621664L
    >>> f.__class__.classattr
    'class'
    >>> id(f.__class__.classattr)
    3077724160L
    L'attribut créé est donc bien propre à l'instance.

    @+ et bonnes fêtes
    Merci d'utiliser le forum pour les questions techniques.

  6. #6
    Membre Expert
    Avatar de fred1599
    Homme Profil pro Fred
    Enseignant
    Inscrit en
    juillet 2006
    Messages
    1 805
    Détails du profil
    Informations personnelles :
    Nom : Homme Fred
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2006
    Messages : 1 805
    Points : 2 445
    Points
    2 445

    Par défaut

    On utilise donc bien le même objet bien que les instances soit différentes.
    Je dirais plutôt que les instances sont les objets, et qu'ils diffèrent (heureusement). Les classes sont les patrons de ces objets et il est normal que eux ne diffèrent pas...
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  7. #7
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    Les classes aussi sont des objets, au sens interprétation du code.
    When a class definition is entered, a new namespace is created, and used as the local scope — thus, all assignments to local variables go into this new namespace. In particular, function definitions bind the name of the new function here.

    When a class definition is left normally (via the end), a class object is created. This is basically a wrapper around the contents of the namespace created by the class definition; we’ll learn more about class objects in the next section. The original local scope (the one in effect just before the class definition was entered) is reinstated, and the class object is bound here to the class name given in the class definition header (ClassName in the example).
    Dans ce sens tout ce qui est dit plus haut explique que cela n'est qu'un parcours des espaces de noms, l'objet classe ayant le siens qui est créé lors de la lecture du code.
    Merci d'utiliser le forum pour les questions techniques.

  8. #8
    Membre Expert
    Avatar de fred1599
    Homme Profil pro Fred
    Enseignant
    Inscrit en
    juillet 2006
    Messages
    1 805
    Détails du profil
    Informations personnelles :
    Nom : Homme Fred
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2006
    Messages : 1 805
    Points : 2 445
    Points
    2 445

    Par défaut

    Ok, on s'est mal compris, je parlais dans un sens concret du problème et non de la syntaxe.

    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  9. #9
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    Bonjour,

    Citation Envoyé par fred1599 Voir le message
    Les classes sont les patrons de ces objets et il est normal que eux ne diffèrent pas...
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> class Foo:
    ...     classattr = 0
    ...     def changeattr(self, newattr):
    ...          self.__class__.classattr = newattr
    ... 
    >>> f = Foo()
    >>> f.classattr
    0
    >>> f.changeattr(1)
    >>> f.classattr
    1
    >>> f1 = Foo()
    >>> f1.classattr
    1
    Cela reste un namespace et Python reste très dynamique... (et je ne parle pas des mutables)

    @+
    Merci d'utiliser le forum pour les questions techniques.

  10. #10
    Membre Expert
    Avatar de fred1599
    Homme Profil pro Fred
    Enseignant
    Inscrit en
    juillet 2006
    Messages
    1 805
    Détails du profil
    Informations personnelles :
    Nom : Homme Fred
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2006
    Messages : 1 805
    Points : 2 445
    Points
    2 445

    Par défaut

    Les classes sont les patrons de ces objets et il est normal que eux ne diffèrent pas
    Ce que je veux dire, c'est que l'on peut modifier un dessin technique (une classe) parce-qu'on a fait un oubli ou fait une erreur, il en reste pas moins que la classe une fois créée permet la construction de différents objets (instances) et cette classe ne changera pas, on partira toujours du même dessin technique pour la construction.

    Si on veut changer le comportement de cette classe, on utilisera l'héritage...

    Si on veut créer/modifier dynamiquement une classe, on parlera de metaclass, mais...

    Citation Envoyé par Tim Peters
    Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don't (the people who actually need them know with certainty that they need them, and don't need an explanation about why).
    ça reste des cas très spécifiques.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  11. #11
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    Citation Envoyé par fred1599 Voir le message
    ça reste des cas très spécifiques.
    Oui...
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    class Storage(object):
        _singleton = None
        datas = []
        def __new__(cls, *args, **kwargs):
            if not cls._singleton:
                cls._singleton = super(Storage, cls).__new__(cls, *args, **kwargs)
            return cls._singleton
        def add(self, newdata):
            self.datas.append(newdata)
        def getdata(self):
            return self.datas
        # ...
     
     
    s = Storage()
    s.add(1)
    s1 = Storage()
    print(s1.getdata())
    print(id(s) == id(s1))
    print(s is s1)
    Mais là c'est plus que du hors sujet (et turbocapillotracté comme dirait quelqu’un)

    @+
    Merci d'utiliser le forum pour les questions techniques.

  12. #12
    Membre Expert
    Avatar de fred1599
    Homme Profil pro Fred
    Enseignant
    Inscrit en
    juillet 2006
    Messages
    1 805
    Détails du profil
    Informations personnelles :
    Nom : Homme Fred
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : juillet 2006
    Messages : 1 805
    Points : 2 445
    Points
    2 445

    Par défaut

    Oui, oui mais quand tu modifieras s1, tu modifieras s, ce qui signifie qu'il n'y a en fait qu'une seule instance, mais j'ai toujours eu du mal à voir l'intérêt du singleton que je trouve contre intuitif au principe de base de la classe qui est :
    Une classe permet la construction de plusieurs objets (instances)

    Je n'en perd pas moins qu'il peut être utile, cependant l'inconvénient est de laisser la possibilité de créer une autre instance, trompeur pour l'utilisateur de cette classe, il pourrait croire utiliser un autre objet (différent) alors que ce n'est pas le cas. Il est préférable de lui interdire l'instanciation (le principe du singleton).
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  13. #13
    Expert Confirmé Avatar de PauseKawa
    Homme Profil pro Patrice BLANGARIN
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    juin 2006
    Messages
    2 720
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrice BLANGARIN
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : juin 2006
    Messages : 2 720
    Points : 3 599
    Points
    3 599

    Par défaut

    L'exemple du singleton (toujours aussi controversé comme pattern ) n'est là que pour l'utilisation de _singleton.
    Citation Envoyé par fred1599 Voir le message
    Il est préférable de lui interdire l'instanciation (le principe du singleton).
    C'est ce qui est fait dans la PEP318
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def singleton(cls):
        instances = {}
        def getinstance():
            if cls not in instances:
                instances[cls] = cls()
            return instances[cls]
        return getinstance
     
    @singleton
    class MyClass:
        ...
    Merci d'utiliser le forum pour les questions techniques.

  14. #14
    Modérateur

    Homme Profil pro
    Architecte technique
    Inscrit en
    juin 2008
    Messages
    5 375
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Industrie

    Informations forums :
    Inscription : juin 2008
    Messages : 5 375
    Points : 7 526
    Points
    7 526

    Par défaut

    Citation Envoyé par fred1599 Voir le message
    Oui, oui mais quand tu modifieras s1, tu modifieras s, ce qui signifie qu'il n'y a en fait qu'une seule instance, mais j'ai toujours eu du mal à voir l'intérêt du singleton que je trouve contre intuitif au principe de base de la classe qui est :
    Une classe permet la construction de plusieurs objets (instances).
    Une classe permet de fabriquer une collection d'objets semblables.
    Une collection peut être vide, réduite à N éléments, permettre la création d'un nombre indéfini d'éléments différents (au sens "is").

    singleton, monostate, Borg permettent de traduire ces différentes propriétés.
    Ce sont des patterns de "design".
    Coder ces propriétés sera plus ou moins ardu suivant le langage.
    Il ne sera pas toujours utile ni nécessaire qu'il y ait bijection entre collection au sens "design" et sa réalisation en code.

    c'est que l'on peut modifier un dessin technique (une classe) parce-qu'on a fait un oubli ou fait une erreur, il en reste pas moins que la classe une fois créée permet la construction de différents objets (instances) et cette classe ne changera pas, on partira toujours du même dessin technique pour la construction.
    Supposons que l'objet soit une "chaise".
    Un caillou, un tabouret,... quoi que ce soit pourvu qu'on puisse poser ses fesses dessus fera l'affaire. Il y a pleins de façons pour fabriquer un objet utilisable en tant que chaise.
    En Python, on appelle cela "duck typing".

    Hmm, bonnes fêtes!
    - W
    Architectures Post-Modernes

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •