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