Pergunta

i have source code of a open source project in python, the project has a module(python) and gui using the module the gui is written in qtpython , now while using the gui and preforming various actions in it is there any way that i can know what are the functions being called and from where something like a log and is there any way i can generate uml diagram of the source code so that i can understand it better and contribute to the project.version of python the project is using is 2.7

Foi útil?

Solução

As mentioned in a comment, generating UML from Python is already discussed in this answer. (Keep in mind that Python doesn't actually have to be UML-representable—but if it is, great.)

As for seeing the flow of control at runtime, there are a few ways you could do this. One is by using profiling and/or debugging tools. But let's look at the simplest possible way to log it, which is what you asked for:

You can "log" anything at any time by just printing to the console. You will have to run the app from the command line instead of launching it GUI-style (and on a Mac, this means you have to run the executable/script directly, not any .app bundle that's been built out of it), but then you've got your logging output—and you can use your shell (even Windows cmd) to redirect this to a file for later browsing, if you'd prefer. If this isn't good enough for you, see the logging module built into the standard library.

If you want to know where a function is being called from, you can log a stack trace every time the function gets called. This is a bit ugly, but it provides all the information you could ever want, and you can always write some code to parse the output later. The function traceback.print_stack does exactly that. (If you want to get more fancy, use other functions to extract the information, format if how you want, and log it how you want.)

You do that by adding this line to every function you want to trace:

traceback.print_stack()

Another way to do this is to write a monkey-patcher and apply it to all the functions you care about:

def tracify(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        traceback.print_stack()
        func(*args, **kwargs)
    return wrapper

Now, in the main script, just do this:

InterestingClass.interestingMethod = tracify(InterestingClass.interestingMethod)

Now, every time InterestingClass.interestingMethod gets called, it will print out a stack trace. You don't have to understand how tracify works. If you want to change what it does to the function, just replace the line traceback.print_stack() with whatever you want to do.

So, what if you want to patch every "public" method in a class?

for attr in dir(InterestingClass):
    if not attr.startswith('_'):
        method = getattr(InterestingClass, attr)
        if isinstance(method, instancemethod):
            setattr(InterestingClass, tracify(method))

(This is for Python 2. Python 3 changes things up, making complicated cases much simpler, but trivial cases not quite as trivial.)

What if you want to patch every public method of every class, and every free function, in a module? You can iterate over a module the same way, and check the type of each thing, just as you can with a class.

You could also use the inspect module to do the hard stuff for you. But if you're just learning Python, I think copying and pasting the dir code is much simpler than learning how to use inspect. Once you're more comfortable with the language, come back and play with inspect to figure out why it all worked.

Outras dicas

I don't use Python, but when you want to trace in real time what a program is doing, you use a debugger, and doing a bit of googling for a Python debugger may give you some promising results.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top