Hi Andrea, excuse my beeing criptic (you wrote: "I have some troubles understanding what you mean") but I coudn't to go on too long. Now I can conclude my speech... When I was younger I transformed a big Clipper program in simil-C in order to apply cflow... and I succeeded... but Clipper wasn't OO! To better explain I must introduce cflow... <code>From: http://www.gnu.org/software/cflow/manual/cflow.txt
/* whoami.c - a simple implementation of whoami utility */ #include <pwd.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> int who_am_i (void) #~13 { struct passwd *pw; char *user = NULL; pw = getpwuid (geteuid ()); #~18 if (pw) user = pw->pw_name; else if ((user = getenv ("USER")) == NULL) #~21 { fprintf (stderr, "I don't know!\n"); #~23 return 1; } #~26 printf ("%s\n", user); return 0; } int main (int argc, char **argv) #~31 { if (argc > 1) { fprintf (stderr, "usage: whoami\n"); #~35 return 1; } return who_am_i (); #~38 } Running `cflow' produces the following output: $ cflow whoami.c main() <int main (int argc,char **argv) #~:31>: | ~ all C programs start with main() +-- fprintf() ~ called from #~35 +-- who_am_i() <int who_am_i (void) #~13 ~ #~38 +-- getpwuid() ~ #~18 +-- geteuid() ~ #~18 +-- getenv() ~ #~21 +-- fprintf() ~ #~23 +-- printf() ~ #~26 </code< This is a direct call graph showing "caller--callee" dependencies Now let us analyse a python script...In this case the presence of OO constructs makes much more difficult to obtain a call graph... (at least for me!). To better show the problems, I take for example a very small script. <code> # 2instances.py # from: http://www.freenetpages.co.uk/hp/alan.gauld/tutclass.htm # w/ some adds up class C: def __init__(self, val): self.val = val def f(self): print "hello, my value is:", self.val # create two instances a = C(27) b = C(42) def E(): #~15 print 'hello '+ F() G() #~17 def F(): #~18 return raw_input('Addressed to ') #~19 def G(): #~21 print 'Hello world' # first try sending messages to the instances a.f(),'************' # hello, my value is 27 b.f() # hello, my value is 42 # now call the method explicitly via the class C.f(a) # hello, my value is 27 # Addressing functions E() #~35 G() #~36 """ call tree w/o classes and objects: E() #~15 called from #~35 +-- F() #~18 16 | +-- raw_input('Addressed to ') # called from 19 +-- G() #~21 18 G() #~21 36 """ </code> Beeing the script so small, the above call tree can be build up by hand, but in every case in am not able to incorporate classes, instances and method calls... Instead, if I move "all" the OO references to a module (for example m2instancesOO.py saved in the same dir as the part w/o OO) I could fictitiously trasform OOP in "procedural" programming, getting therefore only function definitions and calls. It not an easy task... therefore I called help. in my experience, I am convinced that call trees (together with xref) are the main tools to understand not trivial python programs. Instead of using debuggers, with these tools (and with the judicious use of trace) you can solve any bug and besides that acquire a better understanding of the program. Another advantage of moving OO stuff to modules is the "sharp increase in re-usability of code... In my understanding modules are the python's implementation of libraries very much used by other languages. Bye. -- http://mail.python.org/mailman/listinfo/python-list