Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Les pointeurs en python ou de la différence entre une liste et une string et les objets custom

+4 votes

Quand on passe un objet en paramètre à une fonction, ou que l'on crée une instance d'un objet à partir d'un autre objet, ça peut ou pas rester le même objet.
Comme je suis pas clair et qu'un peu de code suffira à vous faire comprendre :

>>> a = "str"
>>> b = a
>>> a += "b"
>>> a
'strb'
>>> b
'str'
>>> c = ["list"]
>>> d = c
>>> c += ["d"]
>>> c
['list', 'd']
>>> d
['list', 'd']

Je pense que tout le monde a compris.
Comment faire, donc, pour deviner dans quel cas on se trouve lorsque l'on utilise des objets provenant de modules, comme les objets QListWidgetItem de PyQt qui se comportent comme les listes (j'aurai pu m'en douter vu le nom en même temps...) ou les objets Path de path.py qui se comportent comme des strings (dont ils dérivent) ?

demandé 2-Jun-2015 par Laërte (346 points)

2 Réponses

+5 votes
 
Meilleure réponse

Ce que tu cherches, c'est de savoir si ton objet est mutable (comme les listes) ou immutables (comme les str)

Commment deviner si c'est l'un ou l'autre sur un objet importé : des éléments de réponse sur SO si tu n'es pas allergique a l'anglais (et ca n'a pas l'air si évident que cà a généraliser)

répondu 2-Jun-2015 par jc (2,674 points)
sélectionné 3-Jun-2015 par Laërte

Je suis pas sûr de tout avoir compris, mais pour l'essentiel je pense avoir saisi l'idée...

Ok.

C'est vrai que la réponse a la question que j'ai pointé n'est pas limpide.
Il y a une partie qui concerne uniquement les dictionaires (points 1,2,3) et du principe de hashability. Les deux sont liés mais c'est un autre probleme, pas la peine de se polluer avec maintenant, mais cette réponse en donne une bonne définition si tu veux creuser.

Je vais essayer de développer :

  • un objet mutable c'est un objet dont la valeur peut être modifié (comme tes listes)
  • a l'inverse unobjet immutable c'est un objet dont la valeur ne peut pas etre modifié (comme tes str).

Pour bien s'en rendre compte, l'exemple de @boblinux dans sa réponse est pertinent : tu peux effectivement voir que les rérérences des objets changent (avecla fonction id()) suivant les opérations que tu fais dessus.

Ce qui modifie un objet, ce sont les opérations que tu effectue dessus, a savoir des appels de ses propres méthodes.
Un objet non modifiable, c'est donc un objet dont aucune de ses méthodes ne modifie sa valeur.

A titre d'exemple, quand tu fais un += sur un objet, tu passes en réalité dans sa méthode __iadd__. Le résultat retourné est dépendant du code de cette méthode.

  • dans le cas d'une str, cette méthde va créer une nouvelle instance qui contiendra la valeur de l'instance courante concaténée au second terme.
  • dans le cas d'une liste, cette méthde va ajouter les éléments de la liste donnée en second terme a l'instance courante et renvoyer l'instance courante

Pour dire qu'un objet est immutable, il faut donc un moyen de vérifier qu'aucune de ses méthodes ne modifie sa valeur : c'est ca qui est compliqué a généraliser.

+1 vote

inspiré de la remarque de @jc partant du fait que le but de la question est la distinction entre les objets mutables et non-mutables, on peut répondre comme suit :

pour voir si un objet est mutable ou non, il suffit de regarder son id lorsqu'on essaye de le modifier.

par exemple avec un objet non-mutable (dont un nouvel id sera crée à chaque modif, car en fait c'est un nouvel objet de quoi il s'agit, sachant qu'on ne peut pas modifier l'objet en question):

>>> s = "abc"
>>>id(s)
4702124
>>> s[0] 
'a'
>>> s[0] = "o"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> s = "xyz"
>>>id(s)
4800100
>>> s += "uvw"
>>>id(s)
4800500

maintenant exemple d'objet mutable, donc l'id sera fixe même quand on modifie l'objet vu qu'il est mutable :

>>> i = [1,2,3]
>>>id(i)
2146718700
>>> i[0] 
1
>>> i[0] = 7
>>> id(i)
2146718700

Sources / lecture : post SO, doc data model

ps : tout est objet en python
pss : il n'y a pas lieu de parler de pointeur car c'est un concept qui n'existe pas en python (on parle plutôt de référence)

répondu 2-Jun-2015 par boblinux (3,094 points)
edité 2-Jun-2015 par boblinux
...