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 :

question sur les références, valable aussi en Python 3 je pense. [Python 2.X]


Sujet :

Python

  1. #1
    Futur Membre du Club Avatar de Whistle
    Inscrit en
    Octobre 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 6
    Points : 8
    Points
    8
    Par défaut question sur les références, valable aussi en Python 3 je pense.
    Bonjour,

    je suis plutôt développeur C++, et je fais occasionnellement du python. J'aime assez, car tout semble plus simple en python. Cependant, la logique du langage est différente, et je bute sur un truc qui, une fois n'est pas coutume, me paraitrait plus simple à faire en C++. Je dois parfaire ma connaissance python, car je suis sur que ce n'est pas si compliqué (j'ai commandé le Apprendre à programmer avec Python 3 par Gérard Swinnen pour avoir un vrai cours python, plutôt qu'un apprentissage "sur le tas")

    Je vais illustrer mon propos avec du code lancé sous IDLE (très pratique d'ailleurs!)
    Je lance des process avec l'objet Popen du module subprocess:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    >>> p1 = subprocess.Popen("echo toto1")
    >>> p2 = subprocess.Popen("echo toto2")
    >>> p3 = subprocess.Popen("echo toto3")
    Apres je peux afficher les PID des process. En réalité, ici les process sont déja terminés donc les pid ne veulent plus dire grand chose mais c'est pour l'exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    >>> p1.pid
    6096
    >>> p2.pid
    8104
    >>> p3.pid
    9560
    Plutôt que de manipuler directement les variables p&, p2 et p3, je vais créer une liste de références vers ces objets:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    >>> L = [p1, p2, p3]
    >>> L
    [<subprocess.Popen object at 0x0000000002D8A198>, <subprocess.Popen object at 0x0000000002D8A3C8>, <subprocess.Popen object at 0x0000000002D8A2B0>]
    >>> L[0].pid
    6096
    Maintenant je vais redéfinir un des process:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    >>> p1 = subprocess.Popen("echo toto1 encore")
    >>> p1.pid
    4688
    Le PID est different, c’est normal. Le problème est que dans la liste l’objet n’est pas mis à jour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    >>> L[0].pid
    6096
    6096 c’est l’ancienne valeur! Dans la liste on a une référence vers l’ancien objet, d’où l’ancien résultat.

    Mais du coup, comment faire ? En C++ j'instancierais quelques objets pour créer des process puis je me ferais une liste de pointeurs sur ces objets pour y acceder. Mais en python "p1" est une référence, du coup je ne vois pas comment faire pour garder une liste de ces instances d'objets Popen ?

    une idée ?

  2. #2
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    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 : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Bonjour,

    J'ai donné des cours de python à mes petits camarades (programmeurs C/C++, passage par valeurs - quitte à passer l'adresse ! -, certains ayant aussi commencé par du Fortran, passage par référence). Je n'ai jamais résussi à faire une analogie qui marche à tous les coups.

    Il faut accepter d'aborder les choses différemment en python. Je t'assure, on s'y fait très bien (j'ai presque 30 ans de C derrière moi et j'arrive à passer d'une philo à l'autre, selon le contexte).

    Dans le cas que tu présentes, tu mets les objets (instances) Popen dans une liste. Avec p1 en première position.

    Mais, à partir du moment où, plus loin, tu écris p1 = qqch, tu crées une nouvelle variable p1. Qui n'a plus rien à voir avec ta liste[0].

    [EDIT] Et donc, si tu veux toujours modifier le p1 initial, il faut taper sur L[0]
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  3. #3
    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 Whistle Voir le message
    Mais du coup, comment faire ? En C++ j'instancierais quelques objets pour créer des process puis je me ferais une liste de pointeurs sur ces objets pour y acceder. Mais en python "p1" est une référence, du coup je ne vois pas comment faire pour garder une liste de ces instances d'objets Popen ?
    C'est une question souvent posée car elle perturbe les débutants en Python.
    A la base, en écrivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    >>> dd = { 'p1': 1, 'p2': 2 }
    on a créé un dictionnaire "dd" contenant 2 paires de clés/valeurs: ('p1', 1), ('p2', 2).
    On peut fabriquer une liste avec ces valeurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> L = [ dd['p1'], dd['p2'] ]
    >>> L
    [1, 2]
    Et dans ce cas, si on assigne une nouvelle valeur à la clé 'p1', il est plus simple de comprendre que cette nouvelle valeur là n'ira pas se propager dans L:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> dd['p1'] = 'x'
    >>> dd
    {'p2': 2, 'p1': 'x'}
    >>> L
    [1, 2]
    >>>
    Maintenant, il suffit de se rappeler qu'une variable n'est rien d'autre que la même association construite dans le dict globals().
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> globals()['p1'] = 'www'
    >>> p1
    'www'
    >>>
    Comment faire?
    De toutes façons, si on veut que l'objet associé à p1 référencé aussi via L[0] puisse être modifié, il faut qu'il soit "mutable". Une liste est "mutable", on peut donc écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> p1 = [1]; p2 = [2]
    >>> L = [ p1, p2 ]
    >>> L
    [[1], [2]]
    Et là, magie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> p1[0] = 'xxx'
    >>> L
    [['xxx'], [2]]
    >>>
    En C++ j'instancierais quelques objets pour créer des process puis je me ferais une liste de pointeurs sur ces objets pour y acceder. Mais en python "p1" est une référence, du coup je ne vois pas comment faire pour garder une liste de ces instances d'objets Popen ?
    Je dirais, on fait pareil (une liste de pointeurs sur...) mais on le réalise différemment.


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

  4. #4
    Futur Membre du Club Avatar de Whistle
    Inscrit en
    Octobre 2009
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Octobre 2009
    Messages : 6
    Points : 8
    Points
    8
    Par défaut
    Merci à plxpy et à wiztricks pour vos réponses!
    Je comprends bien mieux la logique sous-jacente. Je me doutais bien que ce n'était pas si compliqué à obtenir.
    Le truc était de passer directement par la liste, et de faire une liste à objet unique pour satisfaire le besoin de "mutabilité".

    Voici le code, pour ceux qui liront ce thread plus tard, ici adapté à l'objet Popen:
    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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    >>> p1 = [subprocess.Popen("echo toto1")]
    >>> p2 = [subprocess.Popen("echo toto2")]
    >>> L = [p1,p2]
    >>> p1[0].pid
    6428
    >>> p2[0].pid
    8736
    >>> L
    [[<subprocess.Popen object at 0x0000000002C2AA90>], [<subprocess.Popen object at 0x0000000002C2ABE0>]]
    >>> L[0][0].pid
    6428
    >>> L[1][0].pid
    8736
    >>> L[0][0] = subprocess.Popen("echo toto1 encore")
    >>> L[0][0].pid
    2080
    >>> L
    [[<subprocess.Popen object at 0x0000000002C2ACC0>], [<subprocess.Popen object at 0x0000000002C2ABE0>]]
    >>> # les objets sont bien les même qu'au debut, on le voit à leurs adresses
    >>> # et ce, même si on a redéfini le premier objet Popen.
    >>> L[0][0].pid
    2080
    >>> L[0][0].poll()
    0
    >>> # Le process est bien terminé car poll() ne retourne pas None
    >>> L[0][0] = subprocess.Popen("sleep 60")
    >>> L[0][0].poll() is None
    True
    >>> # process pas encore terminé, on attend un peu...
    >>> L[0][0].poll() is None
    False
    >>> # process terminé
    Merci!

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

Discussions similaires

  1. questions sur les références symboliques
    Par Jasmine80 dans le forum Langage
    Réponses: 2
    Dernier message: 15/01/2009, 09h30
  2. Questions sur les références
    Par Az3l_ dans le forum C++
    Réponses: 2
    Dernier message: 11/01/2009, 01h55
  3. Question sur les références.
    Par AsmCode dans le forum C++
    Réponses: 5
    Dernier message: 21/02/2007, 19h57
  4. Encore une question sur les références
    Par bouba dans le forum C++
    Réponses: 7
    Dernier message: 19/02/2007, 14h16
  5. Question sur les références
    Par vdumont dans le forum C++
    Réponses: 7
    Dernier message: 05/05/2006, 01h49

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