Meta decorator with parameters, defined in explicit functions

Chris Angelico rosuav at gmail.com
Sun Jul 3 19:39:35 EDT 2016


On Mon, Jul 4, 2016 at 9:25 AM, Lawrence D’Oliveiro
<lawrencedo99 at gmail.com> wrote:
> On Monday, July 4, 2016 at 10:39:30 AM UTC+12, Ian wrote:
>> Sorry, but you're the one who doesn't seem to get it. Because it's a
>> decorator, "your" function is replacing the caller's function in the
>> caller's namespace.
>
> No it is not. The replacement happens here:
>
>         def generated_decorator(func) :
>             return \
>                 decorator(func, *args, **kwargs)
>         #end generated_decorator
>
> As you can see, the function being called, “decorator”, is supplied by the caller. The function being decorated, “func”, is supplied by the caller (along with the additional *args and **kwargs). And the returned function is returned *as-is*, so whatever docstring was assigned by the caller is *NOT* “clobbered”.
>
> Once again, the only docstrings I am setting are the ones for functions that *I* generate.
>
> Do you understand that yet?

Yes, in a technical sense, you are correct. It's also technically
correct to say that str.upper() doesn't convert its argument to
uppercase - it constructs a completely new string of all uppercase
letters. But in normal usage, people expect "x = x.upper()" to return
*the same string, uppercased*. In the same way, people expect "f =
deco(f)" to return *the same function, decorated*. Technically it's
generally going to be a new function, because functions are immutable
(more-or-less), but it should broadly be the same function.

def require_login(f):
    def modified(*a, **kw):
        if not logged_in:
            return "You must be logged in to do this."
        return f(*a, **kw)
    return modified

@require_login
def fire_ze_missiles():
    raise Exhausted

@require_login
def reboot_server(server):
    """Reboot the specified server"""
    server.send_command("sudo reboot")

Tell me, should the docstring for reboot_server be "Reboot the
specified server", or not? If not, why not?

ChrisA



More information about the Python-list mailing list