Making a decorator a staticmethod

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Thu Jan 8 15:06:29 EST 2009


Zac Burns a écrit :
> I've read the "Making staticmethod objects callable?" thread now, and
> would have to disagree that all the use cases are strange as stated at
> http://www.python.org/dev/summary/2006-03-01_2006-03-15/#making-staticmethod-objects-callable
> 
> In my use case (not the example below)

Then please provide the concrete use case (or at least anything close 
enough)

> the decorator returns a
> function of the form def f(self, *args, **kwargs)

There's nothing magic wrt/ 'self'. Heck, it's not even a keyword.

> which makes use of
> attributes on the instance self.

s/instance self/object passed as first argument/

> So, it only makes sense to use the
> staticmethod in the class and in the baseclass.

Nope. It makes senses for any object implementing the (implied) 
interface, whatever the class or base class.

> Making this decorator
> a module level function doesn't make sense here.

It does, as long as you clearly document the expected interface.

Please understand that what you decorate are plain functions - not 
"methods". Whether the function is being used as the implementation for 
a method or not is totally irrelevant - what's relevant is what the 
decorated function expects as arguments.

wrt/ functions vs methods, technically, there's *no* difference between:

def func(some_interface):
    do_something_depending_on(some_interface)

and

class SomeClassImplementingSomeInterface(object):
     def method(self):
        do_something_depending_on(some_interface)


As a matter of fact, the second snippet is strictly equivalent to:

def func(some_interface):
    do_something_depending_on(some_interface)

class SomeClassImplementingSomeInterface(object):
     pass

SomeClassImplementingSomeInterface.method = func

IOW, a method is implemented by a function (that takes the object as 
first argument). To be true, a Python "method" object is only a thin 
wrapper around a function and an object, that is instanciated (by the 
function object itself) each time an attribute lookup resolves to a 
function object accessed thru the descriptor protocol.

wrt/ decorators: well, a "decorator" is just any callable(that is, any 
object implementing the __call__ method) taking a callable as first 
argument and returning a callable[1].

Now some decorator are generic - they just don't care about the 
decorated function's signature -, and some are not - they expect a (more 
or less) defined argument list. For example, the Django framework 
provides a set of decorators that expects to be applied to callables 
taking an HttpRequest object as first argument. That doesn't mean these 
decorators have to be methods of the HttpRequest class - they are just 
callable that takes as argument a callable which itself takes an 
HttpRequest object as first argument.


[1] and even this definition, while technically mostly correct, doesn't 
cover all acceptations of the term "decorator" - some so-called 
decorators are in fact callables taking some specific argument list and 
returning a proper decorator. That's what you get each time you see 
something like:

@decorate(some_arg)
def some_func(other_arg):
    code_here



HTH



More information about the Python-list mailing list