Bonjour,
J'essaie de traduire en python un bout de code que j'avais écrit en Java et qui pour tout un tas de raisons qu'il serait trop long à expliquer ici, implémente "en ligne" (je ne sais pas si c'est comme ça qu'on dit) une interface. J'utilise python 2.7 et je sais qu'il n'y a pas d'interface parce que héritage multiple, toussa… Mais dans mon code Java l'implémentation de l'interface est stockée dans un attribut (c'est là qu'intervient tout le tas de raisons).
J'ai préparé un petit bout de code pour essayer d'expliciter tout ça :
Mon interface :
public interface Evaluable {
public double eval(double u);
}
Ma classe principale :
public class Courbe {
public Evaluable f;
public Courbe(Evaluable e){
this.f = e;
}
public static void main(String[] args) {
Courbe c = new Courbe(new Evaluable(){
public double eval(double u){
return u*u;
};
});
double resultat = c.f.eval(0.5);
System.out.println("Résultat = " + resultat);
}
}
Comme on peut le voir dans le main, c'est dans l'instanciation de la Courbe c que j'implémente l'interface. Et ça, j'arrive pas à le faire en python :-(
Si quelque âme charitable pourrait m'éclairer de ses lumières…
Merci d'avance.
# Stout bête
Posté par GuieA_7 (site web personnel) . Évalué à 6.
S'il n'y a pas d'interface formelle[*] en Python c'est parce qu'on raisonne en terme de duck-typing, ce n'est pas à cause de la dérivation multiple.
Ton interface dans l'absolu c'est juste un callable (un truc qui s'appelle comme une fonction). Tu peux faire un truc comme ça:
Ou bien avec une "vraie" fonction (que je définis bien ici depuis l'intérieur d'une autre fonction, comme toi):
Voire même avec une classe qui définit la méthode
__call__
et peut donc être appelée comme une fonction:(évidemment si tu tiens vraiment à ta méthode 'eval' tu peux modifier mon dernier exemple, mais je trouve ça moins pythonique).
[*] Ce qui n'est plus tout à fait vrai: https://docs.python.org/release/2.7/library/abc.html#module-abc
[^] # Re: Stout bête
Posté par jMax . Évalué à 2.
Merci pour cette réponse riche d'enseignements. Je pense que je vais apprendre plein de choses en explorant les solutions que tu me proposes. J'espère qu'au moins une d'entre elle sera compatible avec toutes mes contraintes, mais je suis optimiste.
En tout cas, je loue ta magnificence proverbiale.
Bonne journée
[^] # Re: Stout bête
Posté par barmic . Évalué à 3.
Du coup je me pose une question : la manière de faire pour une interface plus complexe (qui a plusieurs méthodes). En java c'est un peu lourd mais ça suit la même syntaxe, en python tu va prendre un objet et lui donner dynamiquement les paramètres qui vont bien ?
Si c'est ça c'est vraiment de la prog par prototypage :)
Par contre je ne sais pas comment créer cet obj. Il n'y a pas (à ma connaissance) de classe maitresse de toutes les autres et instancier une autre classe peu être très artificiel.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: Stout bête
Posté par François GUÉRIN (Mastodon) . Évalué à 2.
Salut,
On peut quand même faire joujou avec une "pseudo" interface, en jouant avec les exceptions
… ou utiliser abc.
[^] # Re: Stout bête
Posté par GuieA_7 (site web personnel) . Évalué à 1.
Je pense que tu as lu un peu vite, ou que je n'ai pas été assez clair.
Il se trouve que dans le cas particulier qui nous importe, l'interface
Evaluable
existe déjà à mon sens dans le langage, et c'est ce que j'appelle un callable (appelable comme une fonction donc). Je lui conseille donc de ne pas traduire le code Java trop bêtement en évitant de définir une nouvelle interface.Mais comme je l'indique dans ma dernière phrase, il peut remplacer
__call__
pareval
(dans ce cas il faudra fairef.eval(1)
et plusf(1)
évidemment), et de même il pourrait rajouter des méthodeseval2
ouzigouigoui
si il veut.Ainsi que François l'explique au dessus, en général tu vas définir une classe AbstractMachin ou BaseBidulos, dans laquelle tu vas mettre des fonctions :
un peu comme tu peux le faire en C++ et ses classes abstraites.
Bon après rajouter des méthodes à un objet/classe ça arrive et parfois ça "sauve la vie", mais on le fait assez rarement.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.