Metaprogrammation et java

Une petite question toute bete, en python je peux faire dans mon programme :

ligne = "print \"toto\"" exec(ligne)
comment fait on la meme chose en java svp ?
Merci
Bussiere

Tu te brosses.

Java n’est pas un langage “dynamique”. Donc tu es obligé de compiler, au moins en mémoire, pour pouvoir effectuer ton traitement.

Après Java 1.6 gère du scripting, ce qui permet de faire à peu près ça.

Python & PHP sont des langages dynamiques. Et transformer un langage “statique” (je ne sais pas si c’est le terme approprié) en dynamique n’est pas une manip très simple (pour preuve l’arrivée du DLR en .NET).

Après je peux être incomplet, je vois des trucs ici-et-là à propos d’une librairie Janino qui permettrait de faire de la compilation dynamique en v5 (ce que la v6 semble réellement apporter c’est une API d’accès au compilateur).

avec java 6: acces au compilateur (java compilation api).
tu compiles ta classes, tu la charges ( avec le class loader) et avec l’instrospection tu lances la méthode qui t’intéresses.
Oui, c’est pas aussi facile qu’en pypy, mais c’est pas un langage interprété, comme le dit styx. Mais j’suis étonné que t’aies besoin de faire ca en java !

[quote=« Bussiere, post:1, topic: 49606 »]Une petite question toute bete, en python je peux faire dans mon programme :

ligne = "print \"toto\"" exec(ligne)
comment fait on la meme chose en java svp ?
Merci
Bussiere[/quote]

Utilise Jython : http://www.jython.org/Project/ :slight_smile: Et le truc bien, c’est que tu n’as même pas besoin de réécrire ton bout de code.

merci a tous
bussiere

Je te recommande l’introspection, c’est pas tout à fait ça, mais c’est plutôt marrant.
En gros tu fais un :

Class c = Class.forname("package.subpackage.classname"); classname toto = (classname)c.newInstance();

Sachant que tu as des getField, et que tu peux (comme en python d’ailleurs) récupérer la liste des méthodes, des champs, des arguments etc …

J’aurai plus dit que ça marche pas car Java est compilé et pas interpreté. Donc tu peux le faire en PHP ou JS, car c’est des langages interprétés

Par contre comment ça marche pour Pyhton ? Ça peut être compilé aussi non?

Mais enfin… si!

Java (comme python) est transformé en bytecode pour être plus facilement interprété, mais ca reste du bytecode a interpréter, et en aucun cas du code-machine.
D’ailleurs, ca serait illogique, il faudrait recompiler pour chaque machine… Pas très pratique pour un langage multi-plateformes.

NOTE: CPython est l’implémentation la plus courante de Python. Il en existe d’autres (dont Jython) qui ne fonctionnent pas forcément sur le même modèle (mais souvent quand meme).

Par contre, la différence, c’est que Java te demande d’avoir créé le bytecode avant de lancer la machine virtuelle et l’interpréteur (dans la plupart des cas). Alors que python s’en occupe si besoin une fois la machine virtuelle/interpréteur lancé.

[quote=“LodeRunner, post:8, topic: 49606”]Mais enfin… si!

Java (comme python) est transformé en bytecode pour être plus facilement interprété, mais ca reste du bytecode a interpréter, et en aucun cas du code-machine.
D’ailleurs, ca serait illogique, il faudrait recompiler pour chaque machine… Pas très pratique pour un langage multi-plateformes.[/quote]

Java est complié en Bytecode, Et c’est pas tres important je pense dans le cadre du thread de savoir si le bytecode est interprété ou pas.

Je pense que c’est très difficile de programmer un fonction eval (qui prendre un string, représentant un programme et qui l exécute dans l’environnement en cours. Si le programme qui fait appelle au eval est compilé. Car le programme doit très difficilement savoir a quoi corresponde les variables passées en paramètre, par rapport a son environnement, c’est a dire dans notre cas, un pile en Java.
En plus une varible qui apparait dans ton source peut aussi avoir viré a la compilation avec une optimisation

Je sais pas si ca a déjà était fait…

En gros c’est facil en php, car dans le cas d’un programme normal, ou d’un programme passé dans une fonction eval, t’es au meme niveau. Alors que dans Java, t’es plus au meme niveau du tout.

ouais enfin dire que le bytecode est interpreté donc Java est un language interpreté c’est aller tres vite en besogne hein :confused:
Autant dire que la machine interprete le code binaire aussi ^^

Ce qui est important de savoir c’est que java necessite un traitement avant d’etre executé.

Le byte code n’est pas interprete. Ca irait serieusement a deux si c’etait le cas (deja que java… oups… j’ai rien dit).

:slight_smile:

D’ailleurs, techniquement, c’est quoi la difference entre la compilation qu’effectue le compilateur C++ et la compilation qu’effectue disont le framework C# ou java ?
Dans les 2 cas, on a un chemin similaire entre le source -> langage intermediaire -> code binaire machine non ?
Enfin, je saisis la pratique de la chose, mais je vois pas la theorie derriere.

Sinon juste pour etre vaguement utile, en C# il y a Reflection.Emit et on peut generer du code a la volee et le faire en MSIL ou autre, et c’est super puissant dans les scenario ou on en a besoin. Et puis la DLR bien sur avec les languages qui vont avec.

[code]Type[] methodArgs = {typeof(int)};
DynamicMethod squareIt = new DynamicMethod(
“SquareIt”,
typeof(long),
methodArgs,
typeof(Example).Module);
ILGenerator il = squareIt.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Conv_I8);
il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Mul);
il.Emit(OpCodes.Ret);

OneParameter<long, int> invokeSquareIt =
(OneParameter<long, int>)
squareIt.CreateDelegate(typeof(OneParameter<long, int>));

Console.WriteLine(“123456789 squared = {0}”,
invokeSquareIt(123456789));[/code]

Alors, vu que Bubu m’a contacté par PM, je poste ici qqes sources intéressantes (moches, certes, mais intéressantes).
Premiere source: invoquer et utiliser le compilateur:

[code]package fr.esiee.bluej.plugin.business;

import java.awt.TextArea;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import javax.annotation.processing.AbstractProcessor;
import javax.swing.JFrame;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;

public class CompilationManager
{
private LinkedList<Class<?>> classesToInstrument;
private List filesToCompile;
private File projectPath;
private File libPath;

public CompilationManager(List<Class<?>> lc,List<File> lf) throws Exception 
{
	this.classesToInstrument = new LinkedList<Class<?>>();
	this.filesToCompile = new LinkedList<File>();
	classesToInstrument.addAll(lc);
	filesToCompile.addAll(lf);		
}


public void runCompilation()
{

	
	if (this.classesToInstrument.size() > 0)
	{
		try 
		{
			///Fliquer les classes			
			// seconde partie
			JavaCompiler compiler;
			compiler = ToolProvider.getSystemJavaCompiler();			
			StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
			Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(this.filesToCompile);

			LinkedList<File> class_path = new LinkedList<File>();
			LinkedList<File> source_output_dirs = new LinkedList<File>();
			
			source_output_dirs.add(new File("/"));
			
			class_path.add(new File("./"));
			class_path.add(projectPath);
			//class_path.add(instrJar);

			fileManager.setLocation(StandardLocation.SOURCE_OUTPUT,source_output_dirs);
			fileManager.setLocation(StandardLocation.CLASS_PATH, class_path);
				

				
			DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
			
			CompilationTask task = compiler.getTask(null, fileManager, 
													diagnostics, null, null, compilationUnits1);
			LinkedList<AbstractProcessor> processors = new LinkedList<AbstractProcessor>();
			processors.add(new InstrumentationProcessor(this.classesToInstrument));
			task.setProcessors(processors);	
			
			if (!task.call())
			{
				String errTxt ="---\n";
				if (diagnostics.getDiagnostics().size()>0)
					for (Diagnostic<?> item : diagnostics.getDiagnostics())
					{
						errTxt += "Diagnostic :"+item.getKind().toString()
						+" a la ligne "+item.getLineNumber()+"\n"
								+ item.getMessage(null)+"\n\n";
					}
				else
					errTxt = " aucun diagnostic.";
				throw new ClassCastException(errTxt);
			}
				

			fileManager.close();
		} 
		catch (IOException e) 
		{
			JFrame essai = new JFrame("Erreur CompilationManager : I/O");
			essai.add(new TextArea(e.getMessage()));
			essai.setSize(200, 200);
			essai.setLocation(500, 500);
			essai.setVisible(true);
		}
		catch (ClassCastException e) 
		{
			JFrame essai = new JFrame("Erreur CompilationManager: resultat compilation des sources generees");
			essai.add(new TextArea(e.getMessage()));
			essai.setSize(200, 200);
			essai.setLocation(500, 500);
			essai.setVisible(true);
		}
		catch (Exception e)
		{
			JFrame essai = new JFrame("Erreur CompilationManager :  Oops!");
			String txt = "";
			//si ca foire...
			for (StackTraceElement elt : e.getStackTrace())
				txt += elt.getClassName()+"."+elt.getMethodName()+" in "+elt.getFileName()+" at "+elt.getLineNumber()+"\n";
			
			essai.add(new TextArea(e.toString()+"\n"+e.getMessage()+"\n"+txt));
			essai.setSize(200, 200);
			essai.setLocation(500, 500);
			essai.setVisible(true);
		}
	}
}

}[/code]
Alors ici tu te fiches de ce qui parle de ‘Processor’. Il s’agit d’objets que tu donnes en parametre au compilateur et qui seront invoqués pour faire un traitement spécial. (ils auront acces a l’arbre de compilation, etc etc)
Les diagnostics sont des ‘callbacks’ en cas d’erreur (point virgule manquant, etc)

Sinon pour ce qui est de l’introspection je ne retrouve pas le code, mais grossièrement chaque objet instancié a une méthode “getClass()” qui elle même a toutes les méthodes qui peuvent t’intéresser (getMethods(), etc). je te conseille de fouiller les API des ClassLoader qui te permettront de charger ta classe une fois compilée.

Pour l’obtenir dans le code tu prends n’importe quelle classe de ton code et tu utilises .getClassLoader().

Pour le pourquoi du comment je poste le code a traduire :
C’est de la metaprogrammation en graphe.
Une sorte de programmation en filet qui peut s’automodifier
un noeud du filet peut changer le maillage et par consequent les autres
ou chaque noeud du filet a un poid ce qui peut aider a choisir en cas de parcour du graphe.

[code]import threading

class Graph:
def init(self,name):
self.name = name
self.list_neighbor = {}
self.list_node = {}
def add_node(self,node):
self.list_node[node] = True

def add_edge(self,node,nodebis):
	try :
		self.list_neighbor[node].append(nodebis)
	except :
		self.list_neighbor[node] = []
		self.list_neighbor[node].append(nodebis)
	try :
		self.list_neighbor[nodebis].append(node)
	except :
		self.list_neighbor[nodebis] = []
		self.list_neighbor[nodebis].append(node)
def neighbors(self,node):
	try :
		return self.list_neighbor[node]
	except :
		return []
def nodes(self):
	return self.list_node.keys()
def delete_edge(self,node,nodebis):
	self.list_neighbor[node].remove(nodebis)
	self.list_neighbor[nodebis].remove(node)
def delete_node(self,node):
	del self.list_node[node]
	try :
		for nodebis in self.list_neighbor[node] :
			self.list_neighbor[nodebis].remove(node)
		del self.list_neighbor[node]
	except :
		return "error"

class Graphe(Graph):
count = 0
liste_node_main = {}
liste_node_type = {}
liste_name = {}
liste_type = {}
liste_weight = {}
liste_key = {}
liste_value = {}
liste_link = {}
liste_func = {}
liste_result = {}
liste_free = {}

def add_node(self,node,name='',type='',weight='',func='',data = ''):
	self.count += 1
	node_coun = self.count
	Graph.add_node(self,node_coun)
	self.liste_node_main[node] = node_coun
	self.liste_node_type[node_coun] = 'main'
	if name != '' :
		self.add_node_name(node,name)
	if type != '':
		self.add_node_type(node,type)
	if func != '':
		self.add_node_func(node,func)
	if data != '':
		self.add_node_data(node,data)
	if weight != '':
		self.add_node_weight(node,weight)


def add_node_weight(self,node,weight):
	node = self.get_real_node(node)
	node_coun = node
	if weight not in self.liste_weight.values():
		self.count += 1
		node_coun = self.count
		print node_coun
		Graph.add_node(self,self.count)
		self.liste_node_type[self.count] = 'weight'
		self.liste_weight[self.count] = weight
	else :
		for key in self.liste_weight :
			if self.liste_weight[key] == weight :
				node_coun = key
	Graph.add_edge(self,node,node_coun)

def add_node_result(self,node,result):
	node = self.get_real_node(node)
	node_coun = node
	if result not in self.liste_result.values():
		self.count += 1
		node_coun = self.count
		Graph.add_node(self,self.count)
		self.liste_node_type[self.count] = 'result'
		self.liste_result[self.count] = result
	else :
		for key in self.liste_result :
			if self.liste_result[key] == result :
				node_coun = key
	Graph.add_edge(self,node,node_coun)

def add_node_data(self,node,data):
	nodes = node
	node = self.get_real_node(node)
	for key in data.keys() :
		if key not in self.liste_key.values() :
			self.count += 1
			node_coun = self.count
			Graph.add_node(self,self.count)
			self.liste_node_type[self.count] = 'key'
			self.liste_key[self.count] = key
		else :
			for keys in self.liste_key :
				if self.liste_key[keys] == key :
					node_coun = keys
		Graph.add_edge(self,node,node_coun)
		if data[key] not in self.liste_value.values() :
			self.count += 1
			node_counv = self.count
			Graph.add_node(self,self.count)
			self.liste_node_type[self.count] = 'value'
			self.liste_value[self.count] = data[key]
		else :
			for keys in self.liste_value :
				if self.liste_value[keys] == data[key] :
					node_counv = keys
		Graph.add_edge(self,node,node_counv)
		Graph.add_edge(self,node_coun,node_counv)
		if [node,node_coun,node_counv] not in self.liste_link.values() :
			self.count += 1
			node_counl = self.count
			Graph.add_node(self,self.count)
			self.liste_node_type[self.count] = 'link'
			self.liste_link[self.count] = [node,node_coun,node_counv]
		else :
			for key in self.liste_link :
			   if self.liste_link[key] == [node,node_coun,node_counv] :
					 node_counl = key
		Graph.add_edge(self,node,node_counl)
		Graph.add_edge(self,node_coun,node_counl)
		Graph.add_edge(self,node_counv,node_counl)









def get_node_weight(self,node):
	node = self.get_real_node(node)
	liste = Graph.neighbors(self,node)
	for n in liste :
		if self.liste_node_type[n] == 'weight' :
			return self.liste_weight[n]

def get_node_data(self,node):
	node = self.get_real_node(node)
	liste = Graph.neighbors(self,node)
	lister = {}
	for n in liste :
		if self.liste_node_type[n] == 'link' :
			lister[self.liste_key[self.liste_link[n][1]]] = self.liste_value[self.liste_link[n][2]]
	return lister



def get_real_node(self,node):
	return self.liste_node_main[node]

def get_node_surname(self,node):
	k = self.liste_node_main.keys()
	for n in k :
		if self.liste_node_main[n] == node :
			return n

def add_node_name(self,node,name):
	node = self.get_real_node(node)
	node_coun = node
	if (name not in self.liste_name.values()):
		self.count += 1
		node_coun = self.count
		Graph.add_node(self,self.count)
		self.liste_node_type[self.count] = 'name'
		self.liste_name[self.count] = name
	else :
		for key in self.liste_name :
			if self.liste_name[key] == name :
				node_coun = key
	Graph.add_edge(self,node,node_coun)

def get_node_name(self,node):
	node = self.get_real_node(node)
	liste = Graph.neighbors(self,node)
	for n in liste :
		if self.liste_node_type[n] == 'name' :
			return self.liste_name[n]

def get_key_node (self,key):
	for k in self.liste_key.keys() :
		if self.liste_key[k] == key :
			return k
def get_value_node (self,value):
	for k in self.liste_value.keys() :
		if self.liste_value[k] == value :
			return k

def add_node_type(self,node,type):
	node = self.get_real_node(node)
	node_coun = node
	if type not in self.liste_type.values():
		self.count += 1
		node_coun = self.count
		Graph.add_node(self,self.count)
		self.liste_node_type[self.count] = 'type'
		self.liste_type[self.count] = type
	else :
		for key in self.liste_type :
			if self.liste_type[key] == type :
				node_coun = key
	Graph.add_edge(self,node,node_coun)

def get_node_type(self,node):
	node = self.get_real_node(node)
	liste = Graph.neighbors(self,node)
	for n in liste :
		if self.liste_node_type[n] == 'type' :
			return self.liste_type[n]

def add_node_func(self,node,func):
	node = self.get_real_node(node)
	node_coun = node
	if func not in self.liste_func.values():
		self.count += 1
		node_coun = self.count
		Graph.add_node(self,self.count)
		self.liste_node_type[self.count] = 'func'
		self.liste_func[self.count] = func
	else :
		for key in self.liste_type :
			if self.liste_func[key] == func :
				node_coun = key
	Graph.add_edge(self,node,node_coun)

def get_node_func(self,node):
	node = self.get_real_node(node)
	liste = Graph.neighbors(self,node)
	for n in liste :
		if self.liste_node_type[n] == 'func' :
			return self.liste_func[n]

def __exec_func(self,func,node):
	dataold = self.get_node_data(node)
	data = self.get_node_data(node)
	exec(func)
	var = None
	for key  in data.keys():
		if data[key] != dataold[key] :
			self.change_node_data(node, data)
	self.add_node_result(node, var)
	self.liste_free[node] = 1

def get_node_result(self,node):
	while self.liste_free[node] != 1 :
		pass
	node = self.get_real_node(node)
	liste = Graph.neighbors(self,node)
	lister = []
	for n in liste :
		if self.liste_node_type[n] == 'result' :
			lister.append(self.liste_result[n])
	return lister

def exec_node_func(self,node):
	self.liste_free[node] = 0
	nodec = self.get_real_node(node)
	liste = Graph.neighbors(self,nodec)
	for n in liste :
		if self.liste_node_type[n] == 'func' :
			t = threading.Thread(target=self.__exec_func, args=(self.liste_func[n],node))
			t.start()

def get_neighbors(self,node):
	node = self.get_real_node(node)
	liste = Graph.neighbors(self,node)
	lister = []
	for n in liste :
		if self.liste_node_type[n] == 'main' :
			lister.append(self.get_node_surname(n))
	return lister

def add_edge(self,node,nodebis):
	Graph.add_edge(self,self.get_real_node(node),self.get_real_node(nodebis))

def change_node_name(self,node,name):
	nameold = self.get_node_name(node)
	nodes = node
	node = self.get_real_node(node)
	for key in self.liste_name :
			if self.liste_name[key] == nameold :
				node_coun = key
	Graph.delete_edge(self,node,node_coun)
	if Graph.neighbors(self,node_coun) == []:
		del self.liste_node_type[node_coun]
		del self.liste_name[node_coun]
		Graph.delete_node(self,node_coun)
	self.add_node_name(nodes,name)

def change_node_type(self,node,type):
	typeold = self.get_node_type(node)
	nodes = node
	node = self.get_real_node(node)
	for key in self.liste_type :
			if self.liste_type[key] == typeold :
				node_coun = key
	Graph.delete_edge(self,node,node_coun)
	if Graph.neighbors(self,node_coun) == []:
		del self.liste_node_type[node_coun]
		del self.liste_type[node_coun]
		Graph.delete_node(self,node_coun)
	self.add_node_type(nodes,type)

def change_node_weight(self,node,weight):
	weightold = self.get_node_weight(node)
	nodes = node
	node = self.get_real_node(node)
	for key in self.liste_weight :
			if self.liste_weight[key] == weightold :
				node_coun = key
	Graph.delete_edge(self,node,node_coun)
	if Graph.neighbors(self,node_coun) == []:
		del self.liste_node_type[node_coun]
		del self.liste_weight[node_coun]
		Graph.delete_node(self,node_coun)
	self.add_node_weight(nodes,weight)

def change_node_func(self,node,func):
	funcold = self.get_node_func(node)
	nodes = node
	node = self.get_real_node(node)
	for key in self.liste_func :
			if self.liste_func[key] == funcold :
				node_coun = key
	Graph.delete_edge(self,node,node_coun)
	if Graph.neighbors(self,node_coun) == []:
		del self.liste_node_type[node_coun]
		del self.liste_func[node_coun]
		Graph.delete_node(self,node_coun)
	self.add_node_func(nodes,func)

def get_liste_node(self):
	return self.liste_node_main
def get_nodes(self):
	listeretour = []
	for node in self.liste_node_main :
		liste = {}
		liste['number'] = node
		liste['type'] = self.get_node_type(node)
		liste['name'] = self.get_node_name(node)
		liste['weight'] = self.get_node_weight(node)
		liste['func'] = self.get_node_func(node)
		liste['data'] = self.get_node_data(node)
		listeretour.append(liste)
	return listeretour

def change_node_data(self,node,data):
	dataold = self.get_node_data(node)
	for keys in data.keys() :
		key = keys
		value = dataold[keys]
	nodev = self.get_value_node(value)
	nodek = self.get_key_node(key)
	listen = Graph.neighbors(self, nodev)
	for noden in listen :
		if self.liste_node_type[noden] == 'link' and self.liste_link[noden] == [node,nodek,nodev] :
			Graph.delete_edge(self, nodev, node)
			Graph.delete_edge(self, nodev, nodek)
			Graph.delete_edge(self, nodev, noden)
			Graph.delete_edge(self, nodek, noden)
			Graph.delete_node(self, noden)
			print "n %s"%Graph.neighbors(self, nodev)
			if Graph.neighbors(self, nodev) == [] :
				Graph.delete_node(self, nodev)
	node = self.get_real_node(node)
	self.add_node_data(node,data)

def debug(self):
	j = 0
	for node in Graph.nodes(self):
		j +=1
		if self.liste_node_type[node] == 'link' :
			print "node : %s type : %s value : %s neighbors : %s"%(node,self.liste_node_type[node],self.liste_link[node],Graph.neighbors(self,node

))
else :
if self.liste_node_type[node] == ‘value’ :
print “node : %s type : %s value : %s neighbors : %s”%(node,self.liste_node_type[node],self.liste_value[node],Graph.neighbors(self,nod
e))
else :
if self.liste_node_type[node] == ‘key’ :
print “node : %s type : %s value : %s neighbors : %s”%(node,self.liste_node_type[node],self.liste_key[node],Graph.neighbors(self,node)
)
else :
if self.liste_node_type[node] == ‘main’ :
print “node : %s type : %s neighbors : %s”%(node,self.liste_node_type[node],Graph.neighbors(self,node))
else:
if self.liste_node_type[node] == ‘weight’ :
print “node : %s type : %s value : %s neighbors : %s”%(node,self.liste_node_type[node],self.liste_weight[node],Graph.neighbors(self,no
de))
else :
if self.liste_node_type[node] == ‘type’ :
print “node : %s type : %s value : %s neighbors : %s”%(node,self.liste_node_type[node],self.liste_type[node],Graph.neighbors(self,node
))
else :
if self.liste_node_type[node] == ‘name’ :
print “node : %s type : %s value : %s neighbors : %s”%(node,self.liste_node_type[node],self.liste_name[node],Graph.neighbors(self,node
))
else :
if self.liste_node_type[node] == ‘func’ :
print “node : %s type : %s value : %s neighbors : %s”%(node,self.liste_node_type[node],self.liste_func[node],Graph.neighbors(self,node
))

	return j

def get_meta_graphe(self):
	liste = {}
	for node in Graph.nodes(self):
		if self.liste_node_type[node] == 'link' :
			liste[node] = {'type' : self.liste_node_type[node],'value' :self.liste_link[node],'neighbors':Graph.neighbors(self,node)}
		else :
			if self.liste_node_type[node] == 'value' :
				liste[node] = {'type' : self.liste_node_type[node],'value' :self.liste_value[node],'neighbors':Graph.neighbors(self,node)}
			else :
				if self.liste_node_type[node] == 'key' :
					liste[node] = {'type' : self.liste_node_type[node],'value' :self.liste_key[node],'neighbors':Graph.neighbors(self,node)}
				else :
					if self.liste_node_type[node] == 'main' :
						liste[node] = {'type' : self.liste_node_type[node],'value' : '','neighbors':Graph.neighbors(self,node)}
					else:
						if self.liste_node_type[node] == 'weight' :
							liste[node] = {'type' : self.liste_node_type[node],'value' :self.liste_weight[node],'neighbors':Graph.neighbors(self,node)}
						else :
							if self.liste_node_type[node] == 'type' :
								liste[node] = {'type' : self.liste_node_type[node],'value' : self.liste_type[node],'neighbors':Graph.neighbors(self,node)}
							else :
								if self.liste_node_type[node] == 'name' :
									liste[node] = {'type' : self.liste_node_type[node],'value' : self.liste_name[node],'neighbors':Graph.neighbors(self,node)}
								else :
									if self.liste_node_type[node] == 'func' :
										liste[node] = {'type' : self.liste_node_type[node],'value' :self.liste_func[node],'neighbors':Graph.neighbors(self,node)}
	return liste

if name == “main”:
G=Graphe(name=“I have a name!”)
G.add_node(1,“node1”,‘node’,3,“data[‘data1’] = 2*data[‘data3’]”,{‘data1’:1,‘data2’:‘toto’,‘data3’:4})
G.add_node(2,“node2”,‘nod’,4,‘self.add_node_data(node,self.get_node_data(node-1))’,{‘data’:0,‘data2’:‘toto’,‘data3’:3})
G.add_edge(1,2)
print G.get_neighbors(1)
print G.get_node_data(1)
print G.get_node_data(2)
print G.get_nodes()
G.change_node_weight(2, 6)
print G.debug()
print G.get_node_weight(2)
G.exec_node_func(1)
print “result : %s”%G.get_node_result(1)
print G.get_node_data(1)
G.exec_node_func(2)
G.get_node_result(2)
print G.get_node_data(2)
print G.get_meta_graphe()[/code]

[quote=« Bussiere, post:16, topic: 49606 »][code]import threading

class Graph:
def init(self,name):
self.name = name
self.list_neighbor = {}…[/code][/quote]

Mais où sont les accolades et les points virgules ??? :slight_smile:

Y’a que moi qui trouve le python illisible ?

[quote=« ZGoblin, post:17, topic: 49606 »]Mais où sont les accolades et les points virgules ??? :slight_smile:

Y’a que moi qui trouve le python illisible ?[/quote]
Disons que ca correspond pas a ce qu’on peut etre habitue a faire, comme coller des accolades partout ou signifier une fin d’instruction par un « ; »

Me semble que le python fonctionne par tabulations, donc les blocs sont definis par l’indentation. C’est un style, ca oblige aussi a garder la meme indentation, a faire attention a ses blocs de code. Je suppose que le langage contraint aussi a 1 « instruction » par ligne (d’ou l’absence de marqueur de fin de statement)

Apres c’est pas tant le langage qui est illisible, c’est juste son code.

[quote=« ZGoblin, post:17, topic: 49606 »]Mais où sont les accolades et les points virgules ??? :slight_smile:

Y’a que moi qui trouve le python illisible ?[/quote]

Perso je met des points-virgules, ça marche aussi.

Par contre ne pas avoir d’accolades c’est vachement mieux au contraire, va me dire que c’est plus lisible d’avoir des accolades… Oui dans Python l’indentation est syntaxique, c’est vachement cool. Et ça force à indenter correctement, ce qui est cool si vous devez former des débutants…

Ca n’existe pas le switch en python ?