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 16/06/2012, à 17:00

PengouinPdt

[python] hashlib :: Création dynamique de fonction

Bonjour !

Dans le code avec lequel je fais mumuse, en ce moment, je joue avec python et hashlib.

class Bidule:

    self.algos = hashlib.algorithms

    def create_filehash(self):

        for a in self.algos:
            if a == self.algo:
                self.fileHash = hashlib.new( a )

- 'self.algos' étant ma liste d'algos disponible
- 'self.algo', l'algorithme choisi par l'action utilisateur - ce qui n'est pas décrit ici, nous sommes d'accord -

Comme chacun le voit ici, j'utilise le constructeur générique new de la bibliotheque hashlib, pour spécifier dynamiquement quel algorithme utilisé.
Le code fonctionne. C'est bien.
Sauf que la doc python nous dit :

The named constructors are much faster than new() and should be preferred

En gros, qu'il vaut mieux utiliser les constructeurs nommés car ils sont plus rapides que le constructeur générique new, n'est-ce pas ?!

Déjà que c'est hyper rapide avec le constructeur générique, mais cette sensation est certainement dû à mon quadri-coeurs, qu'est-ce que cela doit être avec les constructeurs nommés ?! Mais je m'éloigne de mon propos tongue

Comment puis-je modifier ma méthode 'create_filehash' pour choisir dynamiquement le constructeur nommé adéquat selon le choix utilisateur ?


Ego ~
YUP.py :: Yet Uploader Pixxie.py :: script python : post d'images sur forum !

Hors ligne

#2 Le 16/06/2012, à 17:28

PengouinPdt

Re : [python] hashlib :: Création dynamique de fonction

Dans un premier temps, je viens de me rendre compte que j'aurais pu écrire ma méthode ainsi :

    def create_filehash(self):
        if self.algo in self.algos :
            self.fileHash = hashlib.new( self.algo )

Ce qui me semble préférable tongue


Ego ~
YUP.py :: Yet Uploader Pixxie.py :: script python : post d'images sur forum !

Hors ligne

#3 Le 17/06/2012, à 13:24

PengouinPdt

Re : [python] hashlib :: Création dynamique de fonction

Personne n'a d'idée ?


Ego ~
YUP.py :: Yet Uploader Pixxie.py :: script python : post d'images sur forum !

Hors ligne

#4 Le 17/06/2012, à 14:04

pingouinux

Re : [python] hashlib :: Création dynamique de fonction

Bonjour,
Si j'ai bien compris, c'est peut-être ceci que tu veux :

$ cat test.py
#! /usr/bin/python
# -*- coding: utf-8 -*-

import sys, hashlib

class Bidule:

    def __init__(self,algo) :
        self.algos = hashlib.algorithms
        self.algo = algo

        if self.algo in self.algos :
           self.fileHash = hashlib.new( self.algo )

h=Bidule('md5');
h.fileHash.update('12345')
print(h.fileHash.hexdigest())

class Bidul1:

    def __init__(self,algo) :
        self.algos = hashlib.algorithms
        self.algo = algo

        if self.algo in self.algos :
           exec('self.fileHash = hashlib.%s()'%(self.algo))

h=Bidul1('md5');
h.fileHash.update('12345')
print(h.fileHash.hexdigest())
$ ./test.py
827ccb0eea8a706c4c34a16891f84e7b
827ccb0eea8a706c4c34a16891f84e7b

Attention : Le exec peut être dangereux si on lui donne n'importe quoi en argument (code exécutable, par exemple).

Dernière modification par pingouinux (Le 17/06/2012, à 14:07)

Hors ligne

#5 Le 17/06/2012, à 16:52

PengouinPdt

Re : [python] hashlib :: Création dynamique de fonction

@pingouinux: merci.

Je suppose très fortement que la fonction exec() est l'équivalent de la fonction eval() en PHP, et pose assurément les mêmes problèmes !

Bon, alors, je retourne à mon problème et fournis ici une solution que j'espère intéressante :

    def create_filehash(self):

        if self.algo in self.algos and hashlib.__dict__.__getitem__( self.algo ):
            self.fileHash = hashlib.__dict__.__getitem__( self.algo )()

J'ai compris que le dictionnaire d'une classe renferme les méthodes de celle-ci.
J'ai compris qu'il existait des méthodes de classe spéciales - que l'on retrouve dans la doc python :: Data model : special name
J'ai donc cherché et testé celle qui pourrait m'aider à utiliser la méthode recherché, si elle existe ...

Ce qui m'évite d'utiliser la "diabolique" fonction exec() tongue

Voili, voilou ...

PS : Au cas où, je viens de le tester avec trois algos de choix différents 'md5', 'sha1', et 'sha256'.
Je génére le calcul de mon hash qui me permet soit de l'afficher, soit de contrôler un fichier...

Dernière modification par PengouinPdt (Le 17/06/2012, à 16:55)


Ego ~
YUP.py :: Yet Uploader Pixxie.py :: script python : post d'images sur forum !

Hors ligne

#6 Le 18/06/2012, à 15:53

valAa

Re : [python] hashlib :: Création dynamique de fonction

Hello,
Un peu plus lisible et "propre" que de passer par le  __dict__, il y a les fonctions builtin hasattr http://docs.python.org/library/functions.html#hasattr et getattr http://docs.python.org/library/functions.html#getattr

Hors ligne

#7 Le 18/06/2012, à 16:04

Jules Petibidon

Re : [python] hashlib :: Création dynamique de fonction

PengouinPdt a écrit :

Sauf que la doc python nous dit :

The named constructors are much faster than new() and should be preferred

En gros, qu'il vaut mieux utiliser les constructeurs nommés car ils sont plus rapides que le constructeur générique new, n'est-ce pas ?!

Ça ne veut pas dire qu'il ne faut pas utiliser hashlib.new, ça veut tout simplement dire que lorsque tu peux utiliser directement hashlib.md5 (par exemple), alors il est idiot de préférer hashlib.new('md5').
Si tu peux pas faire autrement (l'algo à utiliser est déclaré dans une variable par ex), alors hashlib.new(algo) est parfaitement acceptable.

Hors ligne

#8 Le 18/06/2012, à 16:11

PengouinPdt

Re : [python] hashlib :: Création dynamique de fonction

@Petitbidon: oui, oui, j'ai bien compris cela ... il vaut mieux ne signifie pas il est interdit ;-)

@ValAa: merci de ta réflexion !
Du coup, je viens de tester ce code-ci - fonctionnel aussi big_smile - :

    def create_filehash(self):

        try:
            if self.algo in self.algos and hasattr(hashlib, self.algo):
                self.fileHash = getattr(hashlib, self.algo)()
        except KeyError:
            self.flag = "error"
            self.mssg = self.text["error_key_hash"] % self.algo

Comme quoi, ça m'a toujours fasciné cette possibilité de faire la même chose de manière différente. Avec Python, je trouve cela encore plus existentiel !


Ego ~
YUP.py :: Yet Uploader Pixxie.py :: script python : post d'images sur forum !

Hors ligne

#9 Le 18/06/2012, à 19:50

Keldath

Re : [python] hashlib :: Création dynamique de fonction

Salut,

PengouinPdt a écrit :

@Petitbidon: oui, oui, j'ai bien compris cela ... il vaut mieux ne signifie pas il est interdit ;-)

En fait, tu ne fais que reproduire le comportement de 'hashlib.new()', du coup, tu n'y gagnes pas vraiment en performance je pense.

Code source du module hashlib : http://hg.python.org/cpython/file/6d2a7 … hashlib.py

Hors ligne