Pages : 1
#1 Le 24/03/2010, à 14:19
- no_spleen
[PYTHON] égalité d'objets
Bonjour,
J'ai défini une classe simple comme ceci
class dofkey:
def __init__(self,num,name):
self._num = num
self._name = name
et j'aimerai que 2 objets dofkey définis avec les mêmes arguments soient reconnus comme identiques, hors ce n'est pas le cas
>>> a=dofkey(1,"Test")
>>> b=dofkey(1,"Test")
>>> a==b
False
j'aimerai que le résultat soit True, est-ce réalisable ?
Hors ligne
#2 Le 24/03/2010, à 14:39
- fridobox
Re : [PYTHON] égalité d'objets
Non,
== est l'opérateur qui compare les références, 2 instances d'objet n'ont pas la même référence.
Dans ton cas, on défini une méthode equals(other) dans la classe qui compare le contenu de l'instance self avec l'instance other.
Ubuntero depuis 7.04. Linux registered user number 486328
Hors ligne
#3 Le 24/03/2010, à 14:45
- Michel Leunen
Re : [PYTHON] égalité d'objets
Tu dois implémenter dans ta classe la méthode __eq__ qui va retourner True s'il y a égalité. Par exemple:
def __eq__(self, other):
return (self._num == other._num) and (self._name == other._name)
Michel Leunen
http://linux.leunen.com
Hors ligne
#4 Le 24/03/2010, à 15:09
- no_spleen
Re : [PYTHON] égalité d'objets
Merci, cela marche nickel en définissant la fonction __eq__.
Question subsidiaire, si je veux utiliser la classe dofkey comme clé dans un mapping, je vois sur internet qu'il faut définir la fonction __hash__.
Si je comprend bien, et je ne suis pas sur de comprendre, il faut que cette fonction fournisse un entier, qui sera le même si deux objets sont les mêmes, et différents si deux objets sont différents ???
Si oui, une fonction __hash__ comme celle-ci vous semble-t-elle correcte ?
class dofkey:
def __init__(self,node,name):
self._node = node
self._name = name
def __eq__(self,dofkey):
node = dofkey.getNode()
name = dofkey.getName()
if (self._node == node) and (self._name == name):
return True
else:
return False
def __hash__(self):
value = self.getNode().getNum() * len(self.getName())
if value == -1:
value = -2
return value
def getNode(self):
return self._node
def getName(self):
return self._name
Hors ligne
#5 Le 24/03/2010, à 16:30
- fridobox
Re : [PYTHON] égalité d'objets
Si je comprend bien, et je ne suis pas sur de comprendre, il faut que cette fonction fournisse un entier, qui sera le même si deux objets sont les mêmes, et différents si deux objets sont différents ???
Non.
Le hash est un entier permettant le classer l'objet dans la table de hashage.
La seule contrainte est que si les objets sont identiques (au sens __eq__ retourne true), leur hash doit être identique.
Deux objets différents peuvent avoir le même hash.
Un des buts est d'accélérer la recherche d'un objet dans une table de hashage : on cherche d'abord tous les objets qui ont le même hash puis les compare avec __eq__.
Le hash doit donc être très rapide à calculer.
Je te conseille de faire le hash avec le hash de name.
Ubuntero depuis 7.04. Linux registered user number 486328
Hors ligne
#6 Le 24/03/2010, à 16:57
- no_spleen
Re : [PYTHON] égalité d'objets
Super, je commence à comprendre mieux.
Si j'essaye d'utiliser cette classe dofkey comme clé dans des dictionnaires, l'indexation de nouveaux éléments est très très lente. Est-ce lié à un __hash__ mal choisi, ou bien les dictionnaires sont simplement lents par nature ?
Voici ce que je fait pour rendre les idées claires
class dofkey:
def __init__(self,node,name):
self._node = node
self._name = name
def __eq__(self,other):
node = other.getNode()
name = other.getName()
if (self._node == node) and (self._name == name):
return True
else:
return False
def __hash__(self):
value = hash(self._name)
return value
def getNode(self):
return self._node
def getName(self):
return self._name
class dof_manager:
def __init__(self):
self._numbering = {}
self._fixed = {}
def fixVertex(self,node,name,val):
key = dofkey(node,name)
self._fixed[key] = val
def numberVertex(self,node,name):
key = dofkey(node,name)
if not (key in self._fixed.keys()):
self._numbering[key] = len(self._numbering) + 1
def fixVertices(self,nodes,name,val):
fix = self.fixVertex
for node in nodes:
fix(node,name,val)
def numberVertices(self,nodes,name):
number = self.numberVertex
for node in nodes:
number(node,name)
et dans le programme principal
assem = dof_manager()
assem.fixVertices(Parois,"UX",0.0)
où Parois est une liste de +- 3000 objets noeuds définis dans une autre classe. Le résultat est vraiment très lent par rapport à ce que j'arrive à faire en C++.
En fait, ce programme est la suite d'une discussion sur un autre post, ou je me suis proposé d'écrire un code de calcul scientifique en python pour comparer ses possibilités vis à vis de langages comme fortran ou C++.
Dernière modification par no_spleen (Le 24/03/2010, à 17:13)
Hors ligne
#7 Le 24/03/2010, à 17:45
- fridobox
Re : [PYTHON] égalité d'objets
pour comparer ses possibilités
Lesquels, il faut cibler le but du test.
Je vois pas où le hash intervient ?
Il n'y a que des tableaux.
Ubuntero depuis 7.04. Linux registered user number 486328
Hors ligne
#8 Le 24/03/2010, à 19:12
- no_spleen
Re : [PYTHON] égalité d'objets
Le but est de voir si le temps de calcul en PYTHON n'est pas prohibitif pour du calcul intensif.
Ici, il me semble que le __hash__ de la classe dofkey doit intervenir puisque l'on utilise des dofkey comme index des dictionnaires self._numbering = {} self._fixed = {}.
Hors ligne
#9 Le 25/03/2010, à 10:58
- fridobox
Re : [PYTHON] égalité d'objets
Le but est de voir si le temps de calcul en PYTHON n'est pas prohibitif pour du calcul intensif
Il me semble que le temps de calcul au sens mathématique (addition, multiplication) n'est quasiment pas fonction du langage, c'est le processeur qui s'en occupe.
La performance des langages est fonction de l'optimisation de ses objets de haut niveau (list, dictionnaires ...).
Non ?
Ubuntero depuis 7.04. Linux registered user number 486328
Hors ligne
Pages : 1