473,385 Members | 1,766 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

decorators question

Hi,

i am new to python and i have a question about how decorators are
working.
I have understand HOW they do their magic but i am trying to figure out

WHEN they do it...

I have the following simple example:

#-----------------------------------------
def author(author_name):
def decorator(func):
func.author_name = author_name
return func
return decorator

@author("some author")
def F():
pass

# print F.author_name
#-----------------------------------------
I am using Eclipse/PyDev and when i run this snippet from the PyDev
debugger,
i see that even though i do not call F() (or reference F.author_name),
the decorator and all this stuff is executed and updates F.autor_name
variable.

How is this thing really working ??
I mean, if we run this .py file (pythn test.py) from the command
prompt,
what the runtime will do, even if we do not have ane commands to
execute, only functions
as above ?

It will load all the module, all the functions and when it sees that
some function(s) are decorating, then it will start execute respectives
decorators ?
And this will do it for all decorated functions ?? Even if we do not
have any references to these functions ?

Shouldn't this code called when we actually DO call it ?
Thanks a lot for any enlightment on this,
objectref

Dec 4 '06 #1
13 1245
king kikapu wrote:
It will load all the module, all the functions and when it sees that
some function(s) are decorating, then it will start execute respectives
decorators ?
@decorator
def func():
pass

is *exactly* the same thing as:

def func():
pass
func = decorator(func)
And this will do it for all decorated functions ?? Even if we do not
have any references to these functions ?
Python calls the decorator, not the decorated function.

additional reading:

http://www.python.org/doc/2.4.4/whatsnew/node6.html
http://www.python.org/dev/peps/pep-0318

and the relevant chapters in the tutorial and the language reference.

</F>

Dec 4 '06 #2
def func():
pass

is *exactly* the same thing as:

def func():
pass
func = decorator(func)
Yes, i know that but i thought that it is so when I call the function,
not when the runtime just loads the module...
>Python calls the decorator, not the decorated function.

Hmmm...ok...it calls the decorator but when ?? It (the runtime) loads
the .py file and start to call every decorator
it finds on it, regardless of the existance of code that actually calls
the decorated functions ??
I understand thet Python does not call the decoratated functiond but it
ends up this way...

>
additional reading:

http://www.python.org/doc/2.4.4/whatsnew/node6.html
http://www.python.org/dev/peps/pep-0318

and the relevant chapters in the tutorial and the language reference.
I will have a lokk also thera, thanks!
</F>
Dec 4 '06 #3
Hmmm...ok...it calls the decorator but when ?? It (the runtime) loads
the .py file and start to call every decorator
it finds on it, regardless of the existance of code that actually calls
the decorated functions ??
I understand thet Python does not call the decoratated functiond but it
ends up this way...
Python simply executes the module body when you import a module. class
and def statements result in binding of class and function objects to
the corresponding names. It's really that simple. Try the following to
get a deeper insight:

# file foobar.py

def bar(f):
return 'some text'

@def bar
def foo():
print "foo"
When you import this module module in an interactive python session you
will get he following.
>>from foobar import *
called foo
>>bar() # this will fail because bar is not a function
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'str' object is not callable
>>bar
'some text'

Hope that helps;)
--
Soni Bergraj
http://www.YouJoy.org/
Dec 4 '06 #4
king kikapu wrote:
Hmmm...ok...it calls the decorator but when ?? It (the runtime) loads
the .py file and start to call every decorator
you seem to be missing that the interpreter *always* executes the code
in a module to find out what it contains. "def" and "class" are exe-
cutable statement, not compiler directives. and the decorators are
simply called right after the corresponding "def" statement has been
executed.

</F>

Dec 4 '06 #5
Shouldn't this code called when we actually DO call it ?
Python statements are always executed to create the corresponding class
and function objects when a module is imported.

Cheers,
--
Soni Bergraj
http://www.YouJoy.org/
Dec 4 '06 #6
There was a copy-and-paste error with my last message. Better try this
for foobar.py:

def foo(f):
print "called foo"
return 'some text'
@foo
def bar():
print "called bar"
--
Soni Bergraj
http://www.YouJoy.org/
Dec 4 '06 #7

At first, i am coming from another (language) programming world (C#
mainly) and i hope you understand my wonders.

Ok then, you tell me that the interpreter always execute the code in a
module...If there are only def declarations in the module and no code
to invoke them it does not execute anything. It must have a body (a
call to a(some) method(s)) so it can execute something, right ??

In Soni's example (Soni thanks for the code), it indeed prints "called
foo" but if i remove the @foo statement,
as i see right now in the debugger, it does not execute anything.

I recap: if i put only functions declarations on a .py file, like
these:
def A(): print "a"
def B(): print "b"
def C(): print "c"

and run the program, nothing happens, nothing executed. I have to put a
statment like print A() or b() to cause code execution.

But if i simple declare a decorator for one function, like the one that
Soni gave me, then it caused the deco function to execute. Why is that
??
On Dec 4, 9:46 pm, Soni Bergraj <soniberg...@youjoy.orgwrote:
There was a copy-and-paste error with my last message. Better try this
for foobar.py:

def foo(f):
print "called foo"
return 'some text'
@foo
def bar():
print "called bar"

--
Soni Bergrajhttp://www.YouJoy.org/
Dec 4 '06 #8
king kikapu wrote:
At first, i am coming from another (language) programming world (C#
mainly) and i hope you understand my wonders.

Ok then, you tell me that the interpreter always execute the code in a
module...If there are only def declarations in the module and no code
to invoke them it does not execute anything.
you're not listening. "def" is not a declaration, it's an executable
statement, just like "print" and ordinary assignments and "import" and
"class" and all the others.

the "def" statement itself is *executed* to define the function; it
takes the argument specification and the function code body, and creates
a new function object. the resulting object is assigned to an ordinary
variable.

the only thing that differs if you add a decorator to the mix is that
the function object is passed to the decorator function *before* it's
assigned to a variable.

</F>

Dec 4 '06 #9
On Mon, 2006-12-04 at 14:03 -0800, king kikapu wrote:
I recap: if i put only functions declarations on a .py file, like
these:
def A(): print "a"
def B(): print "b"
def C(): print "c"

and run the program, nothing happens, nothing executed.
Nothing *visible* happens. The "def" statements *do* get executed.
Executing the statement

def A(): print "a"

does the following, roughly, modulo irrelevant implementation details:

* The function body gets compiled into byte code (but not executed).
* A callable object with the byte code for the compiled function body is
constructed.
* The thusly constructed callable object is bound to the name A in your
current namespace.

So, a lot of stuff happens when the interpreter executes a def
statement, but that stuff is not visible to you.

Hope this helps,

Carsten.
Dec 4 '06 #10
Carsten Haese wrote:
* The function body gets compiled into byte code (but not executed).
careful: when you get as far as executing the "def" statement, the
function body has already been compiled. the byte code for the function
is stored as a module-level constant:
>>code = compile("def func(arg): print arg", "", "exec")
dis.dis(code)
1 0 LOAD_CONST 0 (<code object func ...>)
3 MAKE_FUNCTION 0
6 STORE_NAME 0 (func)
....
* A callable object with the byte code for the compiled function body is
constructed.
* The thusly constructed callable object is bound to the name A in your
current namespace.
</F>

Dec 4 '06 #11
On Mon, 2006-12-04 at 23:44 +0100, Fredrik Lundh wrote:
Carsten Haese wrote:
* The function body gets compiled into byte code (but not executed).

careful: when you get as far as executing the "def" statement, the
function body has already been compiled. the byte code for the function
is stored as a module-level constant:
You are, as always, correct, but I deliberately hid this detail inside
the "roughly, modulo irrelevant implementation details" disclaimer in an
attempt of causing the OP the smallest possible amount of confusion.

-Carsten
Dec 5 '06 #12
"king kikapu" <ab********@panafonet.grwrote:
Hmmm...ok...it calls the decorator but when ?? It (the runtime) loads
the .py file and start to call every decorator
it finds on it, regardless of the existance of code that actually calls
the decorated functions ??
I understand thet Python does not call the decoratated functiond but it
ends up this way...
Try this code to help you understand what is going on:

----------- t.py ----------------
import inspect

def adecorator(f):
print "decorating", f.__name__, inspect.getargspec(f)
return f

def makeargument(n):
print "makeargument", n, "called"
return n

print "for loop coming up"
for i in range(3):
print "in for loop, iteration", i
@adecorator
def fn(x=makeargument(i)):
print "fn called, x=", x
print "end of iteration", i

print "now call fn"
fn()
print "done"
---------------------------------

Run it and the output shows you clearly when each element executes.

Note in particular that the def statement inside the loop executes every
time through the loop and each time it creates a new function (which
differs only in the default argument value), the default argument is
evaluated when the def executes, NOT when the function is called.
The decorator is called after the def executes and before the next
statement.
At the end of the for loop we are left only with the last definition of fn:
the others are overwritten during the loop.

The output looks like this:

C:\temp>t.py
for loop coming up
in for loop, iteration 0
makeargument 0 called
decorating fn (['x'], None, None, (0,))
end of iteration 0
in for loop, iteration 1
makeargument 1 called
decorating fn (['x'], None, None, (1,))
end of iteration 1
in for loop, iteration 2
makeargument 2 called
decorating fn (['x'], None, None, (2,))
end of iteration 2
now call fn
fn called, x= 2
done
Dec 5 '06 #13
>you're not listening.

Be sure that i do...The fact that i come from another world does not
mean that i am not listening, just that i find as strange some (new)
things.
Thank you all guys, i know what is happening now...

Thanks again!

kikapu

Dec 5 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Michael Sparks | last post by:
Anyway... At Europython Guido discussed with everyone the outstanding issue with decorators and there was a clear majority in favour of having them, which was good. From where I was sitting it...
12
by: Colin J. Williams | last post by:
Christopher T. King suggested that "we're trying to kill too many birds with one stone". ...
2
by: gohaku | last post by:
Hi everyone, The discussion on Python Decorators and "@" has piqued my interest on this "feature?" in programming languages such as Python and Java. can anybody what is the point in using...
11
by: Arien Malec | last post by:
I've been following the decorator debate with some interest, and it's taken me a reasonably long time to understand what is meant by a decorator. One of the issues is that the Decorator pattern is...
2
by: Guido van Rossum | last post by:
Robert and Python-dev, I've read the J2 proposal up and down several times, pondered all the issues, and slept on it for a night, and I still don't like it enough to accept it. The only reason...
0
by: Anthony Baxter | last post by:
To go along with the 2.4a3 release, here's an updated version of the decorator PEP. It describes the state of decorators as they are in 2.4a3. PEP: 318 Title: Decorators for Functions and...
5
by: John Perks and Sarah Mount | last post by:
When handling resources in Python, where the scope of the resource is known, there seem to be two schools of thought: (1) Explicit: f = open(fname) try: # ... finally: f.close()
7
by: MR | last post by:
Hello All, I have a question about decorators, and I think an illustration would be helpful. Consider the following simple class: #begin code class Foo: def fooDecorator(f): print...
2
by: Andrew West | last post by:
Probably a bit of weird question. I realise decorators shouldn't be executed until the function they are defined with are called, but is there anyway for me to find all the decorates declared in a...
0
by: Gabriel Genellina | last post by:
En Tue, 29 Jul 2008 08:45:02 -0300, Themis Bourdenas <bourdenas@gmail.com> escribi�: In a very strict sense, I'd say that all those references to "method decorators" are wrong - because...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.