0

I've read this SO question and the accepted answer.

Quote:

def overrides(interface_class):
    def overrider(method):
        assert(method.__name__ in dir(interface_class))
        return method
    return overrider

However, I am still not sure, where the parameter method comes from, if I override an arbitrary method.

I'll try to explain what I've understood so far:

  1. The outer function gets its parameter from the notation of the decorator. The decorator gets one parameter, which is the interface, from which we get the method we want to override.
  2. The result of the decorator is a function, which will replace the function, which we decorate with this decorator.
  3. The assert statement checks if the method we want to override is really in the interface, which we gave as a parameter. This is what the actual use is, because now we cannot override not existing methods. If we still try to do this, we will have a failed assertion.

But I still don't get where the parameter method comes from and why it is always the method and not the instance, of the class, in which we want to override a method. A class' method usually has self as a parameter and that refers to the instance, or is that wrong?

I've also read this website. Seems like in their example, the decorator has to take the same parameters the decorated function takes.

So how comes we suddenly have the method and not the class as a parameter?

EDIT#1: On this website I found examples, where the outer function receives the function, which will be decorated, instead of the parameters for that function or the decorator. It seems the logic of how decorators work is dependent on the condition if there are arguments to the decoration or not. But what are those rules?

Example from that website:

def pass_thru(func_to_decorate):
    def new_func(*original_args, **original_kwargs):
        print "Function has been decorated.  Congratulations."
        # Do whatever else you want here
        return func_to_decorate(*original_args, **original_kwargs)
    return new_func


# Notice nothing here now
def print_args(*args):
    for arg in args:
        print arg


# Notice the change here
pass_thru(print_args)(1, 2, 3)
Community
  • 1
  • 1
Zelphir Kaltstahl
  • 5,722
  • 10
  • 57
  • 86
  • 1
    when a callee loves a caller very much they get together and make little parameters, that the stork then drops off in the parenthesis – Joran Beasley Sep 08 '15 at 22:25
  • @JoranBeasley are you saying, that when a method is called, for example like this: `foo(self)` it becomes `foo, self` where the first parameter is always the method name and `self` becomes a message to the method with the method name `foo`? – Zelphir Kaltstahl Sep 08 '15 at 22:42
  • 4
    no sorry I was basically just being a smart ass :/ ... the title made me think of "where do babies come from?" – Joran Beasley Sep 08 '15 at 23:35

1 Answers1

1

Your second point is not valid:

  1. The result of the decorator is a function, which will replace the function, which we decorate with this decorator.

Technically overrides returns the decorator to use for the method. Instead of

class Class(object):
    @overrides(Interface)
    def method(self):
        pass

you could just write

class Class(object):
    overrider = overrides(Interface)
    @overrider
    def method(self):
        pass

As you can find in the motivation for decorators, you'll have a construct equivalent to something like

class Class(object):
    def method(self):
        pass
    method = overrides(Interface)(method)
tynn
  • 38,113
  • 8
  • 108
  • 143
  • I see. Ok, so I've got that decorator as a return value, but how would you describe, how the decorator is applied to the decorated function? – Zelphir Kaltstahl Sep 08 '15 at 23:01
  • @Zelphir hope this helps – tynn Sep 08 '15 at 23:11
  • That'd explain where `method` comes from, but I still don't understand the examples on http://thecodeship.com/patterns/guide-to-python-function-decorators/ then. Why can they use `name`? `name` is not the method, so it seems there is something particular about this case, which makes it different from the one linked. – Zelphir Kaltstahl Sep 10 '15 at 00:39
  • @Zelphir I'm not exactly sure which part you don't understand. `name` is just the parameter of the function getting wrapped and the wrapper as well. – tynn Sep 11 '15 at 15:00
  • I don't understand how it can be the parameter in one case but the function in the other case. How can it be two things? – Zelphir Kaltstahl Sep 12 '15 at 22:44
  • Somehow SO doesn't let me include (at)nickname in the comments, sorry for that. – Zelphir Kaltstahl Sep 15 '15 at 11:47