Function Decorators

I like being able to measure performance of the python functions I code, so very often I do something similar to this...

import time

def some_function(arg1, arg2, ..., argN, verbose = True) :
    t = time.clock() # works best in Windows
    # t = time.time() # apparently works better in Linux

    # Function code goes here

    t = time.clock() - t
    if verbose :
        print "some_function executed in",t,"sec."

    return return_val

Yes, I know you are supposed to measure performance with timeit, but this works just fine for my needs, and allows me to turn this information on and off for debugging very smoothly.

That code of course was from before I knew about function decorators... Not that I know much about them now, but I think I could write a decorator that did the following, using the **kwds dictionary:

some_function(arg1, arg2, ..., argN) # Does not time function
some_function(arg1, arg2, ..., argN, verbose = True) # Times function

I would nevertheless like to duplicate the prior working of my functions, so that the working would be something more like:

some_function(arg1, arg2, ..., argN) # Does not time function
some_function(arg1, arg2, ..., argN, False) # Does not time function
some_function(arg1, arg2, ..., argN, True) # Times function

I guess this would require the decorator to count the number of arguments, know how many the original function will take, strip any in excess, pass the right number of them to the function... I'm uncertain though on how to tell python to do this... Is it possible? Is there a better way of achieving the same?


Asked by: Melanie453 | Posted: 06-12-2021






Answer 1

Though inspect may get you a bit on the way, what you want is in general not possible:

def f(*args):
    pass

Now how many arguments does f take? Since *args and **kwargs allow for an arbitrary number of arguments, there is no way to determine the number of arguments a function requires. In fact there are cases where the function really handles as many as there are thrown at it!


Edit: if you're willing to put up with verbose as a special keyword argument, you can do this:

import time

def timed(f):
    def dec(*args, **kwargs):
        verbose = kwargs.pop('verbose', False)
        t = time.clock()

        ret = f(*args, **kwargs)

        if verbose:
            print("%s executed in %ds" % (f.__name__, time.clock() - t))

        return ret

    return dec

@timed
def add(a, b):
    return a + b

print(add(2, 2, verbose=True))

(Thanks Alex Martelli for the kwargs.pop tip!)

Answered by: John392 | Posted: 07-01-2022



Answer 2

+1 on Stephan202's answer, however (putting this in a separate answer since comments don't format code well!), the following bit of code in that answer:

verbose = False
if 'verbose' in kwargs:
     verbose = True
     del kwargs['verbose']

can be expressed much more clearly and concisely as:

verbose = kwargs.pop('verbose', False)

Answered by: Kelvin201 | Posted: 07-01-2022



Answer 3

it might be difficult but you can do something on these lines. Code below tries to remove any extra arguments and prints them out.

def mydeco(func):
    def wrap(*args, **kwargs):
        """
        we want to eat any extra argument, so just count args and kwargs
        and if more(>func.func_code.co_argcount) first take it out from kwargs 
        based on func.func_code.co_varnames, else last one from args
        """
        extraArgs = []

        newKwargs = {}
        for name, value in kwargs.iteritems():
            if name in func.func_code.co_varnames:
                newKwargs[name] = value
            else:
                extraArgs.append(kwargs[name])

        diff = len(args) + len(newKwargs) - func.func_code.co_argcount
        if diff:
            extraArgs.extend(args[-diff:])
            args = args[:-diff]

        func(*args, **newKwargs)
        print "%s has extra args=%s"%(func.func_name, extraArgs)

    return wrap

@mydeco
def func1(a, b, c=3):
    pass

func1(1,b=2,c=3, d="x")
func1(1,2,3,"y")

output is

func1 has extra args=['x']
func1 has extra args=['y']

Answered by: Haris278 | Posted: 07-01-2022



Similar questions

python - function decorators in c#

Is there a C# analog for Python's function decorators? It feels like it's doable with attributes and the reflection framework, but I don't see a way to replace functions at runtime. Python decorators generally work this way: class decorator(obj): def __init__(self, f): self.f = f def __call__(self...


Function decorators in Ruby, as in Python

Is there a way to decorate a function in Ruby as it's done in Python? That is, have something execute at the beginning (and end?) of each function. Like this: http://programmingbits.pythonblogs.com/27_programmingbits/archive/50_function_decorators.html


Python - Can a function see its own decorators

I'm still very new to Python. Given a function that has decorators, is it possible for the function to access them its body? (from a Fabric script) @task @roles('qa-env') def deploy_qa(): #----------------------------------------------------------------------- # Is there a way to get access to the @roles decorator as an a...


python - Decorators that make the affected function return false?

I have a Django function, read_detail, which returns True or False based on whether a user is allowed to read a page. The function is repeated in several different classes with differing logic, but there is one piece of logic that I think will always be the same, which is returning True if the user is a superuser. I'd like to set it up like this: @is_superuser def read_detail() ...


python - How can I get the decorators of a function?

I have a class, lets called WindCMD, which has functions with decorators @options( [ make_option( '-s', '--windspeed', default = 999, help = "Set the wind speed." ), make_option( '-d', '--winddir', default = 999, help ...


python - How get the called function to loggin with decorators?

I want to write to a log file some events. In order to do this I've used functions decorators to add the loggin code, and report the function called. But, the output is always the same function, the decorator function _decorador. I'm using the %(funcName)s parameter in format logging.basicConfig Output in example.log: 04/21/2014 09:32:41 AM DEBUG This...


python - different decorators for the same function

I have 3 decorators and want to apply each of them to a function individually to create 3 different versions of the function. For example: @decorator_1 def foo1(): blahblah @decorator_2 @decorator def foo2(): blahblah @decorator_3 def foo3() blahblah The contents of foo1, foo2 and foo3 are exactly the same. The problem is I have to write out t...


python - How do decorators mark a function?

I was going throught the basic Flask tutorial which has the following code: from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello World!" if __name__ == "__main__": app.run() Also I went through the basics of Python decorators from many websites including


python decorators, nested function

This question already has answers here:


How to make python decorators work like a tag to make function calls "by tag"

I'm a python beginner and have an idea of the basic concept of decorators. I have worked on Python-Behave before and the framework allows you to insert a decorator and it would function like a tag. I'm trying to replicate this in a framework I'm currently building. custom arg in the CLI parser = argparse.ArgumentParser() parser.add_argument('--type', help='foo help') args = parser.p...


python - How to count function calls using decorators?

I'm refreshing my memory about some python features that I didn't get yet, I'm learning from this python tutorial and there's an example that I don't fully understand. It's about a decorator counting calls to a function, here's the code: def call_counter(func): def helper(x): helper.calls += 1 return func(x...


function - Using a dict as decorators on python

There some way to use a dict as a decorator on python using the default "@" syntax? Like something like: from functools import wraps def deco(f): @wraps(f) def wrapper(*args, **kwargs): print("WRAPPER") return f(*args, **kwargs) return wrapper X={ "deco": deco } # Working @deco def f(): ...


python - How to run function once without using decorators?

When y < x function should run only once and play only one sound, but when I run script it playes more than one. How to run it only once? I tried to solve it with decorators, but I failed. def random_choice(x, y): random_Process = [Process(target=play_sound0).start(), Process(target=play_sound1).start(), Process(target=play_sound2).start()] if y < x: random.choice(rando...


Python 3.5 Decorators and function fields

I have the following snippet of code: def wrapper(func): def wrapped(*args, **kwargs): func.var = 0 return func(*args, **kwargs) return wrapped @wrapper def f_out(): print(f_out.var) Could you please explain to me why running f_out() raises: AttributeError: 'function' object has no attribute 'var' EDIT


function - Why do Python decorators do this? Different Output?

I am relatively new to Python and I was messing around with decorators and I found myself stuck on how to explain the output I was getting after running a decorated function. Here's the code: I first defined a function add like this def add(a, b): '''Returns the sum of two numbers a and b''' return a + b I then created a de...


python - Moving patch decorators into a function

I'm writing tests for models that trigger various functions which go beyond the scope of the testing (some functions invoke network functionality and other undesired things, which are not part of the test, can be slow to just let run and is easier to just switch off for testing purposes). We do this by using a series of @patch decorators above every test function as required. I don't like putting the same decorator...


python - Get names of all function decorators

I would like to apply a decorator to all methods of a class programmatically. With a condition that if a certain decorator already exists, skip adding the decorator to that method. I have something like this code, but I can't figure out the API that would tell me what other decorators may already exist on the method. In my case I want to skip adding cacheable decorator for certain methods which have the...


python - Is there a way to get function output in decorators?

This is my code: def decorator(func): def _(*args, **kwargs): print(args, kwargs, func) result = func(*args, **kwargs) # function result print("Result value is {}".format(result)) return _ @decorator def function(a: int, b: int) -> int: return a + b print(function(2, 2)) In decorator, i'm trying to get the result value, but in order t...


python - How do I make function decorators and chain them together?

How do I make two decorators in Python that would do the following? @make_bold @make_italic def say(): return "Hello" Calling say() should return: "<b><i>Hello</i></b>"


How to make Python help() function work well with decorators?

Python has the nice help() built-in that displays the doc string of an object. When I use it in the REPL passing a function in my module it nicely displays: >>> help(mymodule.myfunction) Help on function myfunction in module mymodule.main: myfunction(parameter=False) -> Dict[str, str] Doc string of myfunction But if I use a decorator like functools.@lru_ca...


python - function decorators in c#

Is there a C# analog for Python's function decorators? It feels like it's doable with attributes and the reflection framework, but I don't see a way to replace functions at runtime. Python decorators generally work this way: class decorator(obj): def __init__(self, f): self.f = f def __call__(self...


unit testing - How to test Python function decorators?

I'm trying to write unit tests to ensure correctness of various decorators I've written. Here's the start of the code I'm trying to write: import unittest from memoizer import Memoizer from strategies.mru import MRU @Memoizer(strategy=MRU(maxsize=10)) def fib(x): if x < 2: return 1 else: return fib(x-1) + fib(x-2) class TestMemoizer(unittest.TestCase): def test_simple(self): self....


Function decorators in Ruby, as in Python

Is there a way to decorate a function in Ruby as it's done in Python? That is, have something execute at the beginning (and end?) of each function. Like this: http://programmingbits.pythonblogs.com/27_programmingbits/archive/50_function_decorators.html


function - Using Decorators in Python for Type Checking

This is more of a syntax error issue, I am trying to do this tutorial on Python Decorators http://www.learnpython.org/page/Decorators My Attempted Code def Type_Check(correct_type): def new_function(old_function): def another_newfunction(arg): if(isintance(arg, correct_type)): retu...


Python - Can a function see its own decorators

I'm still very new to Python. Given a function that has decorators, is it possible for the function to access them its body? (from a Fabric script) @task @roles('qa-env') def deploy_qa(): #----------------------------------------------------------------------- # Is there a way to get access to the @roles decorator as an a...


python - Decorators that make the affected function return false?

I have a Django function, read_detail, which returns True or False based on whether a user is allowed to read a page. The function is repeated in several different classes with differing logic, but there is one piece of logic that I think will always be the same, which is returning True if the user is a superuser. I'd like to set it up like this: @is_superuser def read_detail() ...


python - How can I get the decorators of a function?

I have a class, lets called WindCMD, which has functions with decorators @options( [ make_option( '-s', '--windspeed', default = 999, help = "Set the wind speed." ), make_option( '-d', '--winddir', default = 999, help ...


python decorators getting function variable

I have this code: def check_karma(needed_karma, user_karma): # check karma or exit return True def hello_world(): user_karma = 50 check_karma(20, user_karma) print "Hello World" Can I use decorators here?, something like this: ... @check_karma(20, user_karma) def hello_world(): user_karma = 50 print "Hello World" I don't know i...


How to change function return value with decorators in python?

I have this function and a decorator @decorator(integer) def spam(): return "ABCD EFG" def decorator(number): def inside(function): *do something* return *somthing of type string* return inside I want to make the decorator return FUNCTION, accepts integer and replaces every letter with the letter comming in number places afterwards. For example


python - How get the called function to loggin with decorators?

I want to write to a log file some events. In order to do this I've used functions decorators to add the loggin code, and report the function called. But, the output is always the same function, the decorator function _decorador. I'm using the %(funcName)s parameter in format logging.basicConfig Output in example.log: 04/21/2014 09:32:41 AM DEBUG This...


Python - what are all the built-in decorators?

Closed. This question does not meet Stack Overflow guid...


What are some common uses for Python decorators?

Closed. This question does not meet Stack Overflow guid...


python - Decorators and in class

Is there any way to write decorators within a class structure that nest well? For example, this works fine without classes: def wrap1(func): def loc(*args,**kwargs): print 1 return func(*args,**kwargs) return loc def wrap2(func): def loc(*args,**kwargs): print 2 return func(*args,**kwargs) return loc def wrap3(func): def loc(*args,**kwargs): pr...


language features - How are these type of python decorators written?

I'd like to write a decorator that would limit the number of times a function can be executed, something along the following syntax : @max_execs(5) def my_method(*a,**k): # do something here pass I think it's possible to write this type of decorator, but I don't know how. I think a function won't be this decorator's first argument, right? I'd like a "plain decorator" implementation,...


python - Decorators that are properties of decorated objects?

I want to create a decorator that allows me to refer back to the decorated object and grab another decorator from it, the same way you can use setter/deleter on properties: @property def x(self): return self._x @x.setter def x(self, y): self._x = y Specifically, I'd like it to act basically the same as property, but emulate a sequence instead of a single value. Here's my first sho...


python - function decorators in c#

Is there a C# analog for Python's function decorators? It feels like it's doable with attributes and the reflection framework, but I don't see a way to replace functions at runtime. Python decorators generally work this way: class decorator(obj): def __init__(self, f): self.f = f def __call__(self...


python - How to find which view is resolved from url in presence of decorators

For debugging purposes, I'd like a quick way (e.g. in manage.py shell) of looking up which view that will be called as a result of a specific URL being requested. I know this is what django.core.urlresolvers.resolve does, but when having a decorator on the view function it will return that decorator. Example: >>>django.core.urlresolvers.resolve('/edit_settings/')) (Allow, (), {})


Nice Python Decorators

How do I nicely write a decorator? In particular issues include: compatibility with other decorators, preserving of signatures, etc. I would like to avoid dependency on the decorator module if possible, but if there were sufficient advantages, then I would consider it. Related Preserving s...


python - How to keep help strings the same when applying decorators?

How can I keep help strings in functions to be visible after applying a decorator? Right now the doc string is (partially) replaced with that of the inner function of the decorator. def deco(fn): def x(*args, **kwargs): return fn(*args, **kwargs) x.func_doc = fn.func_doc x.func_name = fn.func_name return x @deco def y(a, b): """This is Y""" pass def z(c, d): """...


Python decorators on class members fail when decorator mechanism is a class

When creating decorators for use on class methods, I'm having trouble when the decorator mechanism is a class rather than a function/closure. When the class form is used, my decorator doesn't get treated as a bound method. Generally I prefer to use the function form for decorators but in this case I have to use an existing class to implement what I need. This seems as though it might be related to






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top