IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Classes paramétrées en Python


Sujet :

Python

  1. #1
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut Classes paramétrées en Python
    Bonjour tout le monde !
    Je voudrais savoir comment en Python réaliser l'équivalent des classes 'template' de C++. J'ai cherché demandé à notre ami Google 'Python template' mais les réponses n'ont apparemment rien à voir avec les classes paramétrées.
    Je vais donner un exemple.
    Je veux modéliser les corps Z/pZ pour p premier d'un seul coup.
    Je sais modéliser Z/2Z, Z/3/Z, Z/5Z.
    Je sais aussi utiliser une variable globale p au niveau du fichier d'implémentation de la classe Z/pZ mais ça c'est vraiment 'quick and dirty', si je veux faire des calculs simultanément dans Z/2Z et Z/3Z vous voyez le problème ...
    Quelqu'un a une idée plus 'clean' ?
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  2. #2
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Et pourquoi ne pas passer "p" en tant que paramètre du constructeur de la classe représentant ces ensembles ?
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  3. #3
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Parce que dans la même classe tu vas avoir des instances de Z/2Z et de Z/3Z, je sais multiplier entre eux des éléments de Z/2Z ou de Z/3Z mais le produit d'un élément de Z/2Z par un autre de Z/3Z c'est quoi ???
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  4. #4
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Après un petit tour sur wiki ... le problème est que la loi multiplicative est une loi de composition interne à la structure d'anneau ?
    Et donc le produit Z/2Z * Z/3Z n'est pas défini ?

    Si c'est bien ça, il reste possible de vérifier que l'opération a un sens au sein de l'opérateur utilisé en comparant la valeur du paramètre "p" des deux instances constituant les deux opérandes de l'opérateur "*".
    Si elle n'en a pas il suffit de lever une exception ou renvoyer "None".
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  5. #5
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Merci, mais en tant qu'algébriste je connais tout ça.
    Après un petit tour sur wiki ... le problème est que la loi multiplicative est une loi de composition interne à la structure d'anneau ?
    Et donc le produit Z/2Z * Z/3Z n'est pas défini
    Au passage le produit Z/2Z * Z/3Z est parfaitement défini, ce qui n'est pas défini c'est le produit d'un élément de Z/2Z par un élément de Z/3Z
    Mon problème n'est pas mathématique...
    Je n'ai donné ceci que comme exemple.
    Mon problème est comment crée-t-on des classes paramétrées en Python ?
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  6. #6
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Salut

    Python n'offre pas de construction similaire au templates du C++ ou generics de Java, car il n'en a pas besoin.

    On peut virtuellement passer n'importe quel type d'argument à une fonction. C'est à la fonction de réagir en selon le type.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    >>> class Z1: pass
    ... 
    >>> class Z2: pass
    ... 
    >>> def test(arg):
    ...     if isinstance(arg, Z1):
    ...         print("C'est un Z1")
    ...     elif isinstance(arg, Z2):
    ...         print("C'est un Z2")
    ... 
    >>> z1 = Z1()
    >>> z2 = Z2()
    >>> test(z1)
    C'est un Z1
    >>> test(z2)
    C'est un Z2
    Vois aussi les méthodes type et issubclass.

    Mais il y a mieux que la méthode ci-dessus, quand tu peux utiliser la surcharge des opérateurs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    >>> class Z1:
    ...     def __init__(self, val):
    ...         self.__val = val
    ...     def __div__(self, divider):
    ...         return self.__val / divider
    ... 
    >>> class Z2:
    ...     def __init__(self, val):
    ...         self.__val = val
    ...     def __div__(self, divider):
    ...         return (self.__val / divider) * 2
    ... 
    >>> z1 = Z1(20)
    >>> z2 = Z2(20)
    >>> def test(arg):
    ...     return arg / 4
    ... 
    >>> test(z1)
    5
    >>> test(z2)
    10
    Mais si tu cherches une solution pour implémenter ces templates avec l'API C de Python, il te suffit de réadapter la solution ci-dessus au C.

  7. #7
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Merci Antoine, mais rien de tout cela n'est nouveau pour moi et cela ne résout pas mon problème.
    Python n'a peut-être pas besoin de classes paramétrées mais moi j'en ai besoin.
    recadrons le débat:
    Je peux faire une classe C2 modélisant Z/2P
    class C2(object):
    def __init__(self,m):
    self.n=m%2
    def __mul__(self, other):
    return C2(self.n*other.n/2)

    etc, etc....
    Bon maintenant, si je veux définir la classe C3 je remplace 2 par 3 et ainsi de suite pour p=5,7,11. C'est crétin.
    Je devrais pouvoir définir toutes les classes Cp avec un paramètre p en une fois.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Points : 102
    Points
    102
    Par défaut
    Alors je ne suis pas sur que cela soit bien propre ce que je vais te proposer, mais j'ai pensé a quelque chose.

    Si au lieu de penser a n declaration de class on pense a une declaration de calss générique, on s'approche de la solution.
    Et donc si on veut faire cela, il suffirait de mettre cette declaration de class dans une fonction a 1 paramettre. ce paramettre etant le "paramettre de class"

    Voila comment je vois les choses:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    def gen_class(name, param):
        class generique_X(object):
            def __init__(self, x):
                self._x = x
            def fonction(x):
                return self._x%param
     
        setattr(__dict__, name+str(param), generique_X)
     
    gen_class(Z, 1)
    gen_class(Z, 2)
    gen_class(Z, 3)
    Je n'ai pas vraiment tester ce code, donc ca ne marche peut être directement en l'état. Mais voila à quoi je pensais. Il y surement des limitation a ce que l'on peut faire avec cette méthode, mais déjà ca permet de faire un certain nombre de choses.

  9. #9
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    @Shadowsam
    Ta proposition a l'air sympa.
    Je vais essayer cela en soirée et je te tiens au courant mais je crois bien que ça va marcher.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  10. #10
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Citation Envoyé par Zavonen Voir le message
    Bon maintenant, si je veux définir la classe C3 je remplace 2 par 3 et ainsi de suite pour p=5,7,11. C'est crétin.
    Je devrais pouvoir définir toutes les classes Cp avec un paramètre p en une fois.
    C'est la première chose à laquelle j'aie pensé, mais je ne vois pas l'utilité d'une classe par diviseur. J'ai peut-être raté un élément primordial à ce besoin, mais est-ce que ce ne serait pas plus simple comme suit ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> class Z:
    ...     def __init__(self, facteur, m):
    ...         self.facteur = facteur
    ...         self.n = m % facteur
    ...     
    ...     def __mul__(self, other):
    ...         return Z(self.facteur, self.n * other.n / self.facteur)
    ... 
    >>> z2 = Z(2, 6)
    >>> z3 = Z(3, 6)
    >>> z2 * z3
    <__main__.Z instance at 0xb7cf412c>
    Mais sauf erreur de ma part, les templates C++ ne permettent pas de donner des valeurs en paramètres, mais seulement des types. Enfin, je me trompe peut-être, et je serais intéressé par un lien

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Points : 102
    Points
    102
    Par défaut
    J'aurais un peu tendance a rejoindre Antoine.

    J'ai pensé un truc qui répond à ce que tu demandes, mais honnêtement je ne comprends pas trop le pourquoi du comment.

  12. #12
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    @Antoine,
    C'est mieux mais j'y avais pensé, le problème est que c'est la même classe et qu'on peut a priori multiplier des congruences modulo des p distincts, ce qui n'a pas de sens mathématique.
    Je crois que je vais me rabattre sur la proposition de shadowsam que j'ai testée et qui fonctionne:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    def GenClasse(p):
        class C(object):
            carac=p
            def __init__(self,x):
                self.z=x%C.carac
            def __str__(self):
                return str(self.z)
            def __mul__(self,other):
                return C((self.z*other.z)%C.carac)
        return C
     
    Z2=GenClasse(2)
    Z3=GenClasse(3)
    z2=Z2(3)
    z3=Z3(2)
    print z2
    print z3
    print z2*z2
    print z3*z3
    Pour les templates en C++ j'en fait une utilisation abondante dans un ressource du forum algo intitulée 'Polynômes à plusieurs variables à coefficients dans un corps quelconque' (sous-forum 'contribuez'), tu peux jeter un coup d'oeil, mais rien ne vaut la doc officielle de Soustrup.
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  13. #13
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Merci, mais en tant qu'algébriste je connais tout ça.
    C'était juste pour être sûr de la problématique.

    Au passage le produit Z/2Z * Z/3Z est parfaitement défini, ce qui n'est pas défini c'est le produit d'un élément de Z/2Z par un élément de Z/3Z
    Oui, bien sûr, la formulation était mal choisie.

    les templates C++ ne permettent pas de donner des valeurs en paramètres, mais seulement des types
    Si et c'est d'ailleurs sur cette fonctionnalité qu'est basée une partie de la métaprogrammation C++ : http://loulou.developpez.com/tutoriels/cpp/metaprog/
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  14. #14
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Citation Envoyé par seriousme Voir le message
    Si et c'est d'ailleurs sur cette fonctionnalité qu'est basée une partie de la métaprogrammation C++ : http://loulou.developpez.com/tutoriels/cpp/metaprog/
    Oh merci pour le lien ! Je viens de survoler, ça a l'air intéressant. J'aurai plus de temps pour lire ça demain.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Diagram Class paramètres entrées non visibles
    Par betsprite dans le forum BOUML
    Réponses: 2
    Dernier message: 18/11/2010, 21h04
  2. Copie profonde sur classe paramétrée
    Par lepak dans le forum Langage
    Réponses: 3
    Dernier message: 07/10/2010, 16h46
  3. apelle en C à partir d'une classe faite en python
    Par julien25 dans le forum Interfaçage autre langage
    Réponses: 4
    Dernier message: 16/03/2009, 22h24
  4. classe osv dans python
    Par fouberge dans le forum Général Python
    Réponses: 2
    Dernier message: 28/08/2008, 12h46
  5. classes abstraites en Python?
    Par areuh_fr dans le forum Général Python
    Réponses: 5
    Dernier message: 07/04/2007, 13h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo