Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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