Dot operator magic has me stymied...

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Casey Rodarmor

    Dot operator magic has me stymied...

    Hi All,

    I'm trying to use a class as a decorator for another class method, but
    it's giving me a lot of grief. Basically, my problem is with the
    example below:
    >>class decorator:
    .... def __init__(self, function):
    .... self.function = function
    ....
    .... def __call__(self, *args, **kwargs):
    .... self.function(* args, **kwargs)
    ....
    >>class Foo:
    .... def __init__(self):
    .... self.msg = "Hello,"
    ....
    .... @decorator
    .... def greet(self, name):
    .... print self.msg, name
    ....
    >>foo = Foo()
    >>foo.greet("Bo b")
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "decorate.p y", line 6, in __call__
    self.function(* args, **kwargs)
    TypeError: greet() takes exactly 2 arguments (1 given)


    I'm guessing that using a decorator that returns a class instance
    instead of a function instance has messed up the magic of the dot
    operator, causing it not to bind the foo instance to the self
    argument.

    Can anybody shed some light on what's happening here?

    Also, I really do like using classes as decorators. Are there any
    workarounds to get it to work with methods?

    Thanks a bunch!

    Best regards,
    Casey Rodarmor
  • Arnaud Delobelle

    #2
    Re: Dot operator magic has me stymied...

    On Oct 29, 7:46 pm, "Casey Rodarmor" <caseyrodar...@ gmail.comwrote:
    Hi All,
    >
    I'm trying to use a class as a decorator for another class method, but
    it's giving me a lot of grief. Basically, my problem is with the
    example below:
    >
    >class decorator:
    >
    ...     def __init__(self, function):
    ...         self.function = function
    ...
    ...     def __call__(self, *args, **kwargs):
    ...         self.function(* args, **kwargs)
    ...>>class Foo:
    >
    ...     def __init__(self):
    ...         self.msg = "Hello,"
    ...
    ...     @decorator
    ...     def greet(self, name):
    ...         print self.msg, name
    ...>>foo = Foo()
    >foo.greet("Bob ")
    >
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "decorate.p y", line 6, in __call__
        self.function(* args, **kwargs)
    TypeError: greet() takes exactly 2 arguments (1 given)
    >
    I'm guessing that using a decorator that returns a class instance
    instead of a function instance has messed up the magic of the dot
    operator, causing it not to bind the foo instance to the self
    argument.
    >
    Can anybody shed some light on what's happening here?
    When

    @decorator
    def greet(self, name):
    print self.msg, name

    is executed, a new decorator object is created whose function
    attribute is the function 'greet' above (with two arguments) and the
    result is given the name 'greet'.

    Later, when
    >>foo = Foo()
    >>foo.greet("Bo b")
    is executed,

    foo.greet is a decorator object whose attribute 'function' is the
    plain function 'greet'. So it expects two arguments and you only
    provide one.

    To fix this you could use the Descriptor protocol. If you don't know
    what it is, I suggest you read this:



    It should give you what you need to get it right.

    HTH

    --
    Arnaud


    Comment

    Working...