On 6/17/07, voltron <[EMAIL PROTECTED]> wrote:
>
> I´m no decorator guru myself, but i dont think that decorators have to
> return functions necessarily. But I had also tried what you suggested,
> that gives me an exception:
>
> exceptions.TypeError: 'NoneType' object is not callable
>
>
> On Jun 17, 10:05 am, Christoph Haas <[EMAIL PROTECTED]> wrote:
> > On Sun, Jun 17, 2007 at 12:47:47AM -0700, voltron wrote:
> > > I am having problems using decorators with controllers. In a test
> > > controller:
> >
> > > # testcontroller.py
> >
> > > def dec(func):
> > > # do lotsa things
> > > print "im doing something"
> > > finished = True
> > > if finished:
> > > func() # call the function you were decorating
> >
> > > class HomeController(BaseController):
> > > def index(self):
> > > return render_response('index.html')
> >
> > > @dec(home)
> > > def test(self):
> > > return render_response('test.html')
> >
> > > tryinf this, I get an error:
> > > exceptions.TypeError: home() takes exactly 1 argument (0 given)
> >
> > > I have to pass "self" to the function passed to the decorator somehow,
> > > what would be the best way to do this? I want the decorator to carry
> > > out a few things before calling the controller function its
> > > decorating.
> >
> > I'm no decoration guru. But don't you have to "return func" in the
> > decorator?
Decorators are tricky enough themselves, but decorators with arguments
are even more tricky. I haven't tried to write one but from what I
understand, the main job of a decorator is to define a *local*
function which calls the wrapped function, and then return the local
function. So you have to replace your decorator with:
def dec(func):
def newfunc():
print "About to call decorated function %s." % func.func_name
rslt = func()
print "Finished calling decorated function %s, result = %r." %
(func.func_name, rslt)
return rslt
return newfunc
@dec
def test(...): ...
I don't understand what you're intending to do with 'home' and
'finished', so I can't put them in my example.
If you put arguments in the @ line, it's a decorator factory; i.e., it
*returns* a decorator rather than "being" a decorator. Typically this
means an additional level of local def, something like this:
def factory(context):
def dec(func):
print "I am doing something wonderful with %r." % context
def newfunc():
print "About to call decorated function."
print "I could do something with 'context'."
print "Maybe I can even pass 'context' to 'func'?"
rslt = func()
print "Finished calling decorated function."
return rslt
@dec(home)
def test(...): ...
The two cases are consistent if you realize that the part following @
is an expression: whatever it evaluates to is the decorator. A
function with arguments is a function call: the return value is the
decorator. A function without () is a function reference: the
function itself is the decorator.
The definitive spec for decorators is
http://python.org/dev/peps/pep-0318/ . The Nose package has several
decorators with arguments n the 'nose.tools' module. They're pretty
straightforward so they'd be good to study.
--
Mike Orr <[EMAIL PROTECTED]>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---