I think I've got it now. But why does this happen?
def a(b):
... b()
...
@a
... def eggs():
... print "spam"
...
spam
eggs()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
--- On Wed, 12/31/08, Lenard Lindstrom <len-l@xxxxxxxxx> wrote:
From: Lenard Lindstrom <len-l@xxxxxxxxx>
Subject: Re: [pygame] @
To: pygame-users@xxxxxxxx
Date: Wednesday, December 31, 2008, 4:05 PM
A concrete example helps. Unfortunately, knowing how a decorator works
does nothing to explain how it is being used any more than know how to
declare a function tells you what all functions do. Anyway, the key
thing to remember is a function declaration in Python is an executable
statement, a function instance is created when execution reaches the
declaration, and that instance is assigned to the variable of the same
name. So:
def fn(x):
return x
fn
<function fn at 0x00C74970>
fn(1)
1
fn = 'this is not a function'
fn
'this is not a function'
when executed, creates an new function instance and assigns it to
identifier fn. However, a decorator is just a function itself. So,
def decorator(f):
print f
return f
@decorator
def fn(x):
return x
<function fn at 0x00C64870>
fn
<function fn at 0x00C64870>
An instance of function fn is created, then function decorator is
called
with that instance as its only argument. decorator then returns the
function instance, which is assigned to identifier fn. So a
decorator is
called when a function declaration is executed, not later when the
function is called.
In the pyglet example "window.event" is a method that accepts a
function
as an argument. In this case 'do_draw' is likely a callback, a
function
that will be called whenever the window receives a draw event. This
alternate code probably would also work:
def on_draw():
....
window.event(on_draw) # return value ignored.
It just saves having to repeat the on_draw function name.
Lenard
Yanom Mobis wrote:
oh. They showed up in some basic example code for pyglet:
import pyglet
window = pyglet.window.Window()
label = pyglet.text.Label('Hello, world',
font_name='Times New Roman',
font_size=36,
x=window..width//2, y=window.height//2,
anchor_x='center', anchor_y='center')
@window.event
def on_draw():
window.clear()
label.draw()
pyglet.app..run()
--- On Wed, 12/31/08, Noah Kantrowitz <noah@xxxxxxxxxxxxxx> wrote:
From: Noah Kantrowitz <noah@xxxxxxxxxxxxxx>
Subject: Re: [pygame] @
To: pygame-users@xxxxxxxx
Date: Wednesday, December 31, 2008, 1:59 PM
No, as I said, decorators are a rather advanced topic. Until you are
more comfortable with the whole compiler process, I would just try
writing a few small ones with various prints to see what happens.
--Noah
On Dec 31, 2008, at 2:57 PM, Yanom Mobis wrote:
class compile?
Anyway, does it effectively work that way?
--- On Wed, 12/31/08, Noah Kantrowitz <noah@xxxxxxxxxxxxxx> wrote:
From: Noah Kantrowitz <noah@xxxxxxxxxxxxxx>
Subject: Re: [pygame] @
To: pygame-users@xxxxxxxx
Date: Wednesday, December 31, 2008, 1:41 PM
No, i has nothing to do with runtime. Decorators are evaluated
during
class compile.
--Noah
On Dec 31, 2008, at 12:05 PM, Yanom Mobis wrote:
Ohhhh! I get it now! It's used to insure that a specific function
is always called before another. Thanks for clearing it up for me..
--- On Wed, 12/31/08, Michael Phipps <michael.phipps@xxxxxxxxxxx>
wrote:
From: Michael Phipps <michael.phipps@xxxxxxxxxxx>
Subject: Re: [pygame] @
To: pygame-users@xxxxxxxx
Date: Wednesday, December 31, 2008, 4:37 PM
Yanom -
A decorator is a method that takes another method as a parameter so
that it can do something.. It is usually used for aspect oriented
programming.
For example:
def logThisMethodCall(methodCall)
# Do some logging here
@logThisMethodCall
def myMethod(a,b,c)
# do Somthing in here
Now, whenever you call "myMethod", logThisMethodCall gets called
first, with the invocation of myMethod passed into it. You can use
it for logging, security (i.e. does this person have permission to
be calling this), etc.
Michael
-----Original Message-----
From: "Yanom Mobis" [yanom@xxxxxxxxxxxxxx]
Date: 12/31/2008 11:19
To: pygame-users@xxxxxxxx
Subject: Re: [pygame] @
so when you do this:
@foo
def bar(): pass
you assume that a function foo() already exists..
and it creates something like this:
def foo():
def bar(): pass
pass
?
I'm sorry, I just got confused.
- On Wed, 12/31/08, Noah Kantrowitz <noah@xxxxxxxxxxxxxx> wrote:
From: Noah Kantrowitz <noah@xxxxxxxxxxxxxx>
Subject: Re: [pygame] @
To: pygame-users@xxxxxxxx
Date: Wednesday, December 31, 2008, 3:01 AM
decorator. The short version is that this
@foo
def bar(): pass
is the same as this
def bar(): pass
bar = foo(bar)
The long version is "look it up because it gets very complicated
and
voodoo-ish"
--Noah
On Dec 30, 2008, at 9:55 PM, Yanom Mobis wrote:
I was reading some Python code examples, and i found the @ symbol.
What
exactly does this operator do?
--
Lenard Lindstrom
<len-l@xxxxxxxxx>