Publié mercredi 9 juillet 2008 19:35 par coucou747

des generateurs python en java (yield)

Apres avoir lu :
http://fr.wikipedia.org/wiki/Python_(programming_language)#G.C3.A9n.C3.A9rateurs

on y trouve un exemple tres interessant :
for n in gen_fibonacci(1000):
print n
cet exemple permet en gros de renvoyer un iterateur. Ce qui est marrant, c'est la syntaxe de l'iterateur... Plutot que de faire un objet, en python, ils ont une instruction qui sert a faire "plusieurs returns values"
def gen_fibonacci(max=sys.maxint):
a=0
b=1
while a<max:
yield a
a,b = b,a+b
c'est marrant comme syntaxe, si on pouvait avoir ca dans d'autres langages, ca serait le pied ;)

le principe est simple : yield sauve le contexte d'execution, et renvoie la valeur. quand on rappelle la fonction, le contexte est concerve.

en java, j'ai fait une classe du meme genre.
public class fibogen extends generator<Integer>{
protected void generateur(){
int d;
int a=0;
int b=1;
while(a<100){
yield(new Integer(a));
d=b;
b+=a;
a=d;
}
}
}
On la lance comme ceci :
fibogen foo = new fibogen();
Integer n;
while (foo.hasNext()){
n = foo.next();
System.out.println(n.toString());
}
bref, je vous presente ma classe, c'est porc, mais c'est marrant

abstract public class generator<T> implements java.util.Iterator<T>, java.lang.Runnable {
Thread t;
T foo;
enum Fin{
Debut, Dernier, Fini
}
Fin next = Fin.Debut;
enum State{
WaitValue, Valued;
}
State state;
public generator(){
t = new Thread(this);
t.start();
getnext();
}
public boolean hasNext(){
return next != Fin.Fini;
}
public T next(){
T n = foo;
if (next != Fin.Dernier) getnext();
else{
next = Fin.Fini;
}
return n;
}
public void getnext(){
state = State.WaitValue;
while (state != State.Valued){
if (next != Fin.Debut){
next = Fin.Fini;
return;
}
Thread.yield();
}
}

public void run(){
generateur();
next = Fin.Dernier;
t.interrupt();
}
protected void yield(T bar){
while (state != State.WaitValue){ Thread.yield(); }
foo = bar;
state = State.Valued;
Thread.yield();
}
abstract protected void generateur();
final public void remove(){}
}
c'est le genre de code que je trouve marrant, mais plutot inutiles dans un vrai projet ;)
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Classé sous , , , , , ,

Les 10 derniers blogs postés

- [WPF] Nouvel article sur c2i.fr par Richard Clark le il y a 15 heures et 44 minutes

- F# nouvelle CTP 1.9.6.2 (update) par Pierrick's Blog le il y a 19 heures et 49 minutes

- La suite ...Proposition de collaboration rédactionnelle entre les communautés de développeurs et Microsoft France par LucasR le 09-05-2008, 17:45

- [Fun] Votre simulateur de vol avec Microsoft ESP par Julien Chable le 09-05-2008, 12:02

- [Best Practices] Customisation du My Site : Comment le modifier en amont et en aval par The Mit's Blog le 09-05-2008, 10:47

- Patrick Tisseghem s'en est allé ... par The Mit's Blog le 09-05-2008, 10:04

- MS AutoCollage par alex# le 09-05-2008, 09:18

- Un grand SharePointeur nous a quitte : Patrick Tisseghem manquera à la communauté ! par RedoBlog - The .NET Gentleman !!! le 09-05-2008, 08:52

- [WPF] Comment charger dynamiquement un fichier XAML qui définit des eventhandler ? par Thomas Lebrun le 09-04-2008, 10:56

- Article sur le filtrage des modèles de site SharePoint par The Grib's Lair [Sébastien PICAMELOT - MVP SharePoint] le 09-04-2008, 00:11