Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Recherche sur les attributs d'un objet (suite)

22 réponses
Avatar
Francois
Bonjour à tous,

en fait, je souhaitais remonter un vieux post. Celui-ci :
http://groups.google.fr/group/fr.comp.lang.python/browse_thread/thread/7fde7231705c24e6
Mais il est trop vieux et n'existe plus dans mon lecteur de news. Donc
j'en créé un nouveau.

Le posteur original du message demandais comment obtenir les attributs
d'un objet. J'avais proposé de faire :

print obj.__dict__

On (Bruno en l'occurrence) avait rectifié en disant ceci :

« Ca ne renverra que les attributs de l'instance. Pour avoir tous les
attributs de l'objet, utilise dir(obj). »

Voici mes questions :

1) Je ne saisi pas trop la différence dans cette phrase entre "attributs
de l'instance" et "attributs de l'objet". Plus exactement, je ne saisi
pas trop la différence dans cette phrase entre "instance" et "objet".
Pour moi, un objet c'est toujours une instance de quelque chose. Donc
pour moi dire "attribut d'instance" ou "attribut d'objet" c'est censé
être la même chose. Est-ce possible d'avoir une explication sur ce point ?

2) J'ai l'impression que dir() affiche bien plus que les attributs d'un
objet. Par exemple avec ceci

#-----------------------
class Mc(object):
version = '1.0'

obj = Mc()
#-----------------------

dir(Mc) et dir(obj) me donneront (entre autres) 'version' comme
"attribut". Mais pour moi version est un attribut de Mc uniquement, mais
pas de obj. Bien sûr, obj.version va me renvoyer '1.0' mais lors de la
recherche de l'attribut, c'est dans l'objet classe Mc que version sera
trouvé et non dans l'objet obj. Est-ce correct ?

Dans ce cas, si obj désigne un objet quelconque (classe ou instance
etc...), existe-t-il une instruction pour afficher uniquement tous les
attributs qui appartiennent à obj et seulement ceux qui appartiennent à
obj ?

Merci d'avance.

--
François

2 réponses

1 2 3
Avatar
Bruno Desthuilliers
Francois a écrit :
Merci pour ta réponse, même si elle m'a plongé dans un abîme de
perplexité. :-)




Niark niark !-)

Bruno Desthuilliers a écrit :
Pour quelle définition de "espace de nom" ?



Je pensais que l'espace de nom (quand il existe) d'un objet O était
l'ensemble de toutes les clés de l'objet dictionnaire o.__dict__ où o
est un identificateur faisant référence à l'objet O.




C'est une des définitions possibles. Une autre serait : l'ensemble de
tous les attributs (au sens de la définition donnée dans un post
précédent) d'un objet.


Bon, ok, là je n'aide pas vraiment à clarifier le débat. Ceci étant,
c'est bien toute l'ambiguïté du terme "attribut" qui se révèle ici. Et
aussi le problème qu'il peut y avoir à vouloir appliquer des concepts
inadéquats à un modèle donné. Dans le cas de Python, on ne travaille
qu'avec des couples nom => référence.



C'est pas plutôt "nom => objet", non ?



Non. Du moins, pas dans le sens où 'nom' serait un alias pour l'adresse
de l'objet.

Pour moi un nom, c'est déjà en
soi une référence à un objet.



En pratique, ça revient à ça. Mais tu n'a pas besoin d'un nom pour avoir
une référence à un objet (cf les listes et tuples...).


Je trouve que l'ambiguïté se fait sentir surtout quand on veut
signifier qu'un attribut est «propre» à un objet ou est un attribut
«tout-court» à l'objet (accessible via l'objet), ambiguïté qui était
à l'origine de ce post d'ailleurs.



Ca va plus loin en fait, puisque le fait que C.m soit résolu par
C.__dict__['m'] (en d'autres termes : (C.m is C.__dict__['m']) ==
True) ne rends pas l'objet accessible par l'une ou l'autre syntaxe
dépendant de C pour son cycle de vie.



Je ne comprends pas cette phrase. Au contraire, il est accessible par
une ou l'autre des syntaxes ?



Excuse moi, je reformule : 'm' in C.__dict__ n'implique pas que le cycle
de vie de l'objet associé à C.__dict__['m'] soit directement dépendant
du cycle de vie de C. Donc, il serait faux de dire que l'objet référencé
par C.__dict__['m'] "appartienne en propre" à C.

En d'autres termes, quelque soit l'objet o tel o is C.m and o is
C.__dict__['m'] n'implique pas que del C ou delattr(C, 'm') ou del
C.__dict__['m'] aient pour résultats de terminer le cycle de vie de o.



car l'objet C.__dict__['m'] peut avoir une référence par d'autre moyen
que par C si je comprends bien ?



Voilà.

J'ai du mail à voir le rapport entre
nos histoires d'attributs et les problèmes de durée de vie des objets.



C'est lié à la notion que tu soulevais d'attribut "propre" à un objet
(sous-entendu : "appartenant en propre" à l'objet). Cette notion n'est
que très relative en Python (contrairement à par exemple C++).


Je reprends l'expression «propre» qui tu avais employée dans ta
première réponse (et qui me plaît bien).



même un attribut "propre" à une instance n'appartient pas à cette
instance.



Je ne suis pas sûr de comprendre. J'ai l'impression, en gros, que tu es
en train de m'expliquer que l'expression "propre" peut-être inadaptée
car elle peut laisser penser l'existence d'une notion d'appartenance qui
ne s'applique pas chez Python, où tout est plutôt histoire de références



Exactement.

qui s'entremêlent de façon plus désorganisée qu'il n'y paraît.



Je te laisse l'entière responsabilité de ce dernier propos...

Pour le moment, c'est un terme "comme ça". Et comme tu peux le
constater, plus on essaie de définir précisément, et plus c'est le
bordel.



Oui.



(snip)

J'aimerais bien savoir si tu es d'accord avec ceci ? (j'ai
*essayé* de tenir compte de tes remarques) :

------------
Soit O un objet donné et o est un identificateur faisant référence à
l'objet O.

a) "L'espace de nom" (quand il existe) de l'objet O est l'ensemble de
toutes les clés de l'objet dictionnaire o.__dict__.



C'est une définition possible, et effectivement la plus courante. A un
détail près : les slots.

b) "L'objet A est un attribut de l'objet O" si et seulement l'objet A
est créé par le programme suite à une référence de la forme o.a ne
levant pas un AttributeError,



Simplifie : "L'objet A est un attribut de l'objet O" si et seulement
l'objet A est accessible une référence de la forme o.a (ou getattr(o,
'a')) ne levant pas un AttributeError,

et où a est un identificateur qu'on
appelle alors le nom de l'attribut A.

c) "L'objet A est un attribut de l'objet O, *résolu* en O" si et
seulement si l'objet A est un attribut de l'objet O (cf b) et si ('a' in
o.__dict__) == True, où a est le nom de l'attribut A.



"résolu en O" est une terminologie qui t'es propre - non qu'elle soit
nécessairement mauvaise, mais tu risques d'avoir du mal à te faire
comprendre. Pour revenir au début de la discussion, je parlerais plutôt
d'"attribut d'instance". C'est en tous cas ainsi qu'on distingue le
sous-ensemble des attributs référencés par le __dict__ (ou un slot) de
l'instance de l'ensemble des attributs de l'objet.

Remarque : Dans le cas c), l'attribut o.a de l'objet O résolu en O n'est
pas forcément le même objet que o.__dict__['a'] ; si O est une classe et
si A un est descripteur par exemple.



Dans ce cas, tout attribut de O est "résolu en O".

Bon, à ce stade, on va arrêter de faire des misères aux drosophiles, je
pense...
Avatar
Francois
Je te remercie vivement pour toutes tes explications. :-)

A+

--
François
1 2 3