rkern / line_profiler

(OLD REPO) Line-by-line profiling for Python - Current repo ->
https://github.com/pyutils/line_profiler
Other
3.6k stars 254 forks source link

Need an ability to set the methods I need to profile from the commandline arguments #85

Open Felix-neko opened 7 years ago

Felix-neko commented 7 years ago

Sometimes I don't want to modify the code I want to profile, so this will be extremely useful.

Felix-neko commented 7 years ago

Also, it will be extremely good if you add the ability to profile all functions and methods of a class (of even of a module).

Alexey-Akishin commented 6 years ago

Both things are already possible. Of course, this issue is still not solved, because at very least, the solution is neither documented nor elegant. But it is better than adding and removing @profile all the item to each method of each class. This is the code I use as workaround for these issues:

no_profile = False  # pylint: disable=C0103
try:
    @profile
    def noop():
        """Dummy function to try decorator."""
        pass
except NameError:
    no_profile = True  # pylint: disable=C0103
if no_profile:
    def profile(function):
        """Dummy decorator - just return the function as is."""
        return function

def for_all_methods(decorator, exclude=None):
    """Apply given decorator for all methods of the class.
    It is possible to exclude some methods by providing their names as a list
    of strings.
    """
    exclude = [] if exclude is None else exclude

    def decorate(cls):
        """Decorated function."""
        for attr in cls.__dict__:
            if callable(getattr(cls, attr)) and attr not in exclude:
                setattr(cls, attr, decorator(getattr(cls, attr)))
        return cls
    return decorate

Then you can just add @for_all_methods(profile) for each class. You will be able to run the code both normally and when you want to profile without any farther modification. Be careful though, line_profile currently not thread-safe, so do not use it in more than one thread at a time.

bje- commented 5 years ago

Yes, but not everyone wants to profile all methods/functions. Just the ability to nominate a single function on the command line would be jolly useful.

AstroMen commented 5 years ago

Hi @Alexey-Akishin , I am not clear the code as below:

try:
    @profile
    def noop():
        """Dummy function to try decorator."""
        pass
except NameError:
    no_profile = True

Which case would raise NameError? What this works for?

Thanks.

Nodd commented 5 years ago

I think the following code is enough:

try:
    profile
except NameError:
    no_profile = True

The code could be simplified :

try:
    profile
except NameError:
    def profile(function):
        """Dummy decorator - just return the function as is."""
        return function