OVH Cloud OVH Cloud

Problème avec une instanciation

5 réponses
Avatar
Tool69
Bonsoir,
Supposons que j'ai cr=E9=E9 une classe Point, comme ceci par exemple:

#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-

class Point(object):

def __init__(self, x, y, z, nom):
self.x =3D x
self.y =3D y
self.z =3D z
self.nom =3D nom

def _get_rens(self):
return 'Point %s de coordonn=E9es :(%d, %d, %d)' %(self.nom,
self.x, self.y, self.z)

rens =3D property(_get_rens)


# Test de la classe Point:
a =3D Point(-2,3,5,"A")
print a.rens

On obtient =E0 la sortie ceci :
Point A de coordonn=E9es :(-2, 3, 5)

J'aimerai ne plus avoir nom d=E9fini comme ici, mais que le script le
g=E9n=E8re automatiquement suivant la variable que je lui donne pour
instancier mon Point.
Par exemple, si j'=E9cris :

b =3D Point(5,-3,10)

je voudrais qu'il me sorte (apr=E8s un "print b.rens") :

Point b de coordonn=E9es :(5,-3,10)

Suis-je bien clair ?
Merci pour vos id=E9es/conseils :

6TooL9

5 réponses

Avatar
Eric Brunel
On Mon, 17 Jul 2006 22:43:39 +0200, Tool69
wrote:

Bonsoir,
Supposons que j'ai créé une classe Point, comme ceci par exemple:

#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-

class Point(object):

def __init__(self, x, y, z, nom):
self.x = x
self.y = y
self.z = z
self.nom = nom

def _get_rens(self):
return 'Point %s de coordonnées :(%d, %d, %d)' %(self.nom,
self.x, self.y, self.z)

rens = property(_get_rens)


# Test de la classe Point:
a = Point(-2,3,5,"A")
print a.rens

On obtient à la sortie ceci :
Point A de coordonnées :(-2, 3, 5)

J'aimerai ne plus avoir nom défini comme ici, mais que le script le
génère automatiquement suivant la variable que je lui donne pour
instancier mon Point.
Par exemple, si j'écris :

b = Point(5,-3,10)

je voudrais qu'il me sorte (après un "print b.rens") :

Point b de coordonnées :(5,-3,10)


Réponse courte: oublie. Réponse plus longue: au moment de la création du
Point, il n'est pas encore affecté à la variable. Il n'a donc aucun moyen
de récupérer la variable à laquelle il est affecté, puisqu'il ne l'est pas
encore. Il y aurait sans doute une bidouille infecte pour essayer de
récupérer l'info au moment où _get_rens est appelée, mais ça ne marcherait
que dans quelques cas.

De toutes façons, il y a plein de cas dans lesquels soit ça ne peut pas
marcher, soit c'est ambigü:

1:
a = Point(1, 2, 3)
b = a # a.rens = ?; b.rens = ?

2:
l = []
for i in range(10): l.append(Point(i, i, i)) # l[4].rens = ?

3:
def f():
x = Point(4, 5, 6) # x.rens = ?
return x
y = f() # y.rens = ?
f().rens # = ?

Suis-je bien clair ?
Merci pour vos idées/conseils :


Y'a pas de mal.
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"

Avatar
Bruno Desthuilliers
Tool69 wrote:
Bonsoir,
Supposons que j'ai créé une classe Point, comme ceci par exemple:

#!/usr/bin/env python
# -*- coding: ISO-8859-1 -*-

class Point(object):

def __init__(self, x, y, z, nom):
self.x = x
self.y = y
self.z = z
self.nom = nom

def _get_rens(self):
return 'Point %s de coordonnées :(%d, %d, %d)' %(self.nom,
self.x, self.y, self.z)

rens = property(_get_rens)


Tu aurais pu utiliser __repr__() pour ça.

(snip le reste, cf réponse de Eric).


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"

Avatar
Tool69
Merci pour vos réponses, j'avais bien vu qu'il existait des problèmes
sur une telle représentation, car on peut déjà instancier un objet
sans lui affecter de variable. Je n'avais pas pensé aux autres
possbilités, notamment les affectations du style b = a doivent
effectivement poser des problèmes.

En ce qui concerne la réponse de Bruno, je ne vois pas comment
__repr__() pourrait m'aider...mais je connais mal cette fonction, je
sais qu'elle est utilisée à la place de __str__() si str n'est pas
définie. Mais comment capturer le nom de ma variable à l'intérieur ?

Merci encore,
6TooL9
Avatar
Bruno Desthuilliers
Tool69 wrote:
Merci pour vos réponses, j'avais bien vu qu'il existait des problèmes
sur une telle représentation, car on peut déjà instancier un objet
sans lui affecter de variable. Je n'avais pas pensé aux autres
possbilités, notamment les affectations du style b = a doivent
effectivement poser des problèmes.

En ce qui concerne la réponse de Bruno, je ne vois pas comment
__repr__() pourrait m'aider...mais je connais mal cette fonction, je
sais qu'elle est utilisée à la place de __str__() si str n'est pas
définie.


Les infos utiles sont dans le Fameux Manuel:

"""
__repr__( self)
Called by the repr() built-in function and by string conversions
(reverse quotes) to compute the ``official'' string representation of an
object. If at all possible, this should look like a valid Python
expression that could be used to recreate an object with the same value
(given an appropriate environment). If this is not possible, a string of
the form "<...some useful description...>" should be returned. The
return value must be a string object. If a class defines __repr__() but
not __str__(), then __repr__() is also used when an ``informal'' string
representation of instances of that class is required.

This is typically used for debugging, so it is important that the
representation is information-rich and unambiguous.
"""

En pratique, ta propriété 'rens()' (dont je suppose que c'est un
raccourci pour 'renseignements()') correspond très exactement à la
sémantique habituellement attachée à __repr__().

Mais comment capturer le nom de ma variable à l'intérieur ?


C'est sans rapport avec ta problématique de "nom de variable" - désolé
si ce n'était pas clair.


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"

Avatar
Pierre Quentel
Je suis d'accord avec les autres réponses, ce n'est pas une bonne
idée

On peut quand même essayer des bidouilles de ce genre :

#!/usr/bin/env python
#-*- coding: ISO-8859-1 -*-

class Point(object):

def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z

def _get_rens(self):
nom = "<inconnu>"
for k in globals():
if globals()[k] is self:
nom = k
break
return 'Point %s de coordonnées :(%d, %d, %d)' %(nom,
self.x, self.y, self.z)

rens = property(_get_rens)

a = Point(1,2,3)
print a.rens


Dans _get_rens() on cherche si un nom global est lié au même objet
que l'instance, et dès qu'on en trouve un, on le prend comme nom de
cette instance

Evidemment si on crée un autre nom avec b = a, a.rens renverra soit a
soit b, le premier trouvé dans les clés de globals()

Pierre