Diez B. Roggisch wrote:
    def decorate(func):
        def _d(*args, **kwargs):
            do_something()
            # call func
            func(*args, **kwargs)
        return _d
    @decorate
    def foo():
        pass
[T]he function decorator has to return a function that is bound to the name
foo in the originating context (module or class) and gets the function
passed as argument. If I want my decorator ... parametrized...:
    @decorate(arg)
    def foo():
        pass
    def decorate(arg):
        def f(func):
            def _d(*args, **kwargs):
                do_something(arg)
                # call func
                func(*args, **kwargs)
            return _d
Now why this layer of indirection?

Let's rewrite your example a bit, it may become obvious. def decorate(func): def replacement(argspec): do_something() return func(argspec) return replacement @decorate def foo(argspec): pass --- def decorate2(): def _decorate(func): def replacement(argspec): do_something() return func(argspec) return replacement return _decorate @decorate() def foo(argspec): pass --- def decorate3(arg): def _decorate(func): def replacement(argspec): do_something() return func(argspec) return replacement return _decorate @decorate3(arg) def foo(argspec): pass --- Clear now? there is no extra indirection. If you call something on the @ line, the _result_of_that_call_ should be a decorator function. If you use my curry recipe in the python cookbook, you can use curry lower the apparent "indirection":

     def decorate4(arg, func):
         def replacement(argspec):
             do_something()
             return func(argspec)
         return replacement
     @curry(decorate4, arg)
     def foo(argspec): pass

By the way, I _do_ think curry is an appropriate name.  The Curry-Howard
isomorphism shows the equivalence of a functions on tuples with single-
argument functions returning functions.  In a functional language, where
there is no distinction made between a a function with no arg and its
result, the transformation is clear.  With a language like Python, which
pays attention to when a function is invoked, you are better off
returning a function which can take the remaining arguments, and
controlling when the final function is called by returning a function
that can take all the remaining arguments at once.

-Scott David Daniels
[EMAIL PROTECTED]
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to