[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] @



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>