473,473 Members | 1,823 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

@decorators

For what it's worth:

As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another. Previously, when looking at:

some_python(code)
and_some_more = stuff

there was no need to look at the the first line in order to know what
the second line meant/did (and vice versa). It would seem that the
cases when there are effects across multiple logical lines is captured
in compound statements:

"""
Compound statements contain (groups of) other statements; they affect
or control the execution of those other statements in some way.
""" -Python Reference Manual

My understanding of decorators is that they fit this definition.
One thing that I am not entirely clear about is whether decorators
are intended to be a compound statement themselves, or whether they
are meant to simply be extensions of current compound statements
such as function definition (and class definitions?)

In either case, however, it seems that the following should apply:

"""
Each clause header begins with a uniquely identifying keyword and ends
with a colon. A suite ... can be one or more indented statements on
subsequent lines.
""" -Python Reference Manual

In the first case where decorators form their own compound statement,
this would seem to imply the basic layout of:

@decorator:
def foo():
pass

(Whether that uniquely identifying keyword for decorators happens to
be spelled '@' is not important to me.)

In the second case where decorators are simply extensions of current
compound statements, the current wording of the Python Reference
Manual would seem to imply that for function definition the clause
header must begin with 'def'. I.e., the decorator should not come
before the def, and certainly not on a separate line. Beyond this,
however, for me it is not particularly important whether the
decorator comes before/after the function name/argument list, and
how it is delimited.

I guess the basic point that I am trying to make is that what I find
important is consistency with the basic visual layout of code promised
(IMHO) by python. I believe that this promise is violated by the
currently proposed decorator scheme.

d

PS: Although I believe the current view of the implementors is to view
decorators as an extension to function definition, I believe that the
separate compound statement view is fairly rich. As others have noted,
it can make identical decorations simpler:

@static,synchronized:
def foo():
pass
def bar():
pass
Jul 18 '05 #1
17 1742
daishi wrote:
For what it's worth:

As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another. Previously, when looking at:

some_python(code)
and_some_more = stuff

there was no need to look at the the first line in order to know what
the second line meant/did (and vice versa). It would seem that the
cases when there are effects across multiple logical lines is captured
in compound statements:

"""
Compound statements contain (groups of) other statements; they affect
or control the execution of those other statements in some way.
""" -Python Reference Manual

My understanding of decorators is that they fit this definition.
One thing that I am not entirely clear about is whether decorators
are intended to be a compound statement themselves, or whether they
are meant to simply be extensions of current compound statements
such as function definition (and class definitions?)

In either case, however, it seems that the following should apply:

"""
Each clause header begins with a uniquely identifying keyword and ends
with a colon. A suite ... can be one or more indented statements on
subsequent lines.
""" -Python Reference Manual

In the first case where decorators form their own compound statement,
this would seem to imply the basic layout of:

@decorator:
def foo():
pass

(Whether that uniquely identifying keyword for decorators happens to
be spelled '@' is not important to me.)

In the second case where decorators are simply extensions of current
compound statements, the current wording of the Python Reference
Manual would seem to imply that for function definition the clause
header must begin with 'def'. I.e., the decorator should not come
before the def, and certainly not on a separate line. Beyond this,
however, for me it is not particularly important whether the
decorator comes before/after the function name/argument list, and
how it is delimited.

I guess the basic point that I am trying to make is that what I find
important is consistency with the basic visual layout of code promised
(IMHO) by python. I believe that this promise is violated by the
currently proposed decorator scheme.

d

PS: Although I believe the current view of the implementors is to view
decorators as an extension to function definition, I believe that the
separate compound statement view is fairly rich. As others have noted,
it can make identical decorations simpler:

@static,synchronized:
def foo():
pass
def bar():
pass

I like this idea. What about using the list syntax instead of the @ syntax:

[decorator]:
def foo():
pass

[static, synchronized]:
def foo():
pass
def bar():
pass

[static,
synchronized,
types(int, int),
returns(None)
]:
def foo():
pass

This would then take away the argument against a valid list before a def
being valid python but not previously having any effect...

Or for good measure you could add a keyword:

declare [static, synchronized, types(int, int), returns(None)]:
def foo():
pass
def bar():
pass

Now that looks pretty neat

David
Jul 18 '05 #2

"daishi" <go****@daishi.fastmail.fm> wrote in message
news:d2**************************@posting.google.c om...
For what it's worth:

As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another.


Examples:

try - except - finally
if - elif - else
while - else

John Roth
Jul 18 '05 #3

"daishi" <go****@daishi.fastmail.fm> wrote in message
news:d2**************************@posting.google.c om...
For what it's worth:

As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another. Previously, when looking at:


I think the @decorator syntax was invented by Microsoft to sabotage Python,

Tom
Jul 18 '05 #4
John Roth wrote:
"daishi" <go****@daishi.fastmail.fm> wrote in message
news:d2**************************@posting.google.c om...
For what it's worth:

As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another.

Examples:

try - except - finally
if - elif - else
while - else


I think he mean two consecutive lines of python code with the same
indentation.

David
Jul 18 '05 #5
daishi:
As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another. Previously, when looking at:

some_python(code)
and_some_more = stuff

there was no need to look at the the first line in order to know what
the second line meant/did (and vice versa).


Much of the time, consecutive lines with the same indentation are highly
dependent with earlier lines modifying the behaviour of successor lines:

global x
x = 9

Neil
Jul 18 '05 #6
"Tom B." <sb******@commspeed.net> wrote in message
news:10***************@news.commspeed.net...

"daishi" <go****@daishi.fastmail.fm> wrote in message
news:d2**************************@posting.google.c om...
For what it's worth:

As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another. Previously, when looking at:

I think the @decorator syntax was invented by Microsoft to sabotage

Python,
Tom


Heeey, let's keep it civil!!!
Jul 18 '05 #7
"Neil Hodgson" <nh******@bigpond.net.au> writes:
global x
x = 9


I think what he meant was that the decorators in effect make for
"hidden continuation", e.g.

@foo
def fooDecorated():
pass

is like

@foo def fooDecorated():
pass:

when other line continuations are explicit.
Jul 18 '05 #8

"Paul McGuire" <pt***@austin.rr._bogus_.com> wrote in message
news:WZ*****************@fe1.texas.rr.com...
"Tom B." <sb******@commspeed.net> wrote in message
news:10***************@news.commspeed.net...

"daishi" <go****@daishi.fastmail.fm> wrote in message
news:d2**************************@posting.google.c om...
For what it's worth:

As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another. Previously, when looking at:


I think the @decorator syntax was invented by Microsoft to sabotage

Python,

Tom


Heeey, let's keep it civil!!!

Your right, I apologize, @decorator syntax will affect me with much less
adversity than Microsoft.

Tom
Jul 18 '05 #9
Tor Iver Wilhelmsen wrote:
I think what he meant was that the decorators in effect make for
"hidden continuation", e.g.

@foo
def fooDecorated():
pass

is like

@foo def fooDecorated():
pass:

when other line continuations are explicit.


Which is *exactly* why I dislike this syntax so much. I don't mind the
"@", though it does look a might out-of-place. What I dislike is the
placement: It relies on setting a "magic state" in the interpreter to
affect the very next thing at the same indentation level. I can't think
of any other place in Python where this sort of thing is done.
Everything else either introduces a new block, or requires bracketing.

Everyone shows the examples like above, but what about the following?

class C:
# This is a really long comment that has little to do
# with the following function; it is here only so that
# the comment wraps. This is a really long comment that
# has little to do with the following function; it is
# here only so that the comment wraps over several lines.
@ staticmethod

# MAB 20040806113000: Added argument baz.
# MAB 20040806112957: Added argument bar.
# MAB 20040806112950: Initial version.
def static_method_foo( bar, baz):
pass

Did you catch it? This method *is* decorated, though it is hard to see
it unless you are really looking for it. Syntax coloring will help, of
course, but not much, and we shouldn't rely on that anyway.

My concern is that the decorator can be separated from the decorated by
an arbitrarily large amount of space. Even ONE blank line is enough for
me to mentally dissociate the decorator from the decorated. Comments
make it worse. Now, would a sane programmer do this? One would hope not,
but there is nothing to prevent it--and I've found that the definition
of "sane" varies widely between programmers.

What I think might work better is to treat these decorators the same way
we already treat docstrings.

def decorated( a, b, c):
@classmethod
@signature( None, a=int, b=float, c=dict)
@transactional( database)
"""\
decorated( a, b, c): A thrice-decorated function.

The silly function does nothing except get "decorated." classmethod
determines the form of the first argument (class, object, or
other). signature changes the call behavior, asserting the types
passed to and returned from the function. Finally, transactional
causes boilerplate code to be executed before and after the function
body, ensuring that either all changes to database are applied, or
none are. Seeing as this function does nothing, this is trivial :).
"""

pass

Personally, I kind of like the "@" syntax in this form. It still sticks
out (and IMHO, it *should* stick out, because it is not a normal
statement), but it also is easier to ignore if you aren't looking for it
because it is explicitly scoped at the function level.

We already expect metadata--namely, the docstring--to be at the top of
the function. This simply extends that idea to include other forms of
metafunctionality. The compiler already looks for metadata at the start
of functions; the special syntax helps the compiler determine which
statements need to be handled immediately, and where the function
implementation starts.

-- Mark
Jul 18 '05 #10
Mark Bottjer wrote:

Mark, would your example still be acceptable to you if someone wrote
it like this?:
def sillyFunction( a, b, c):
"""\
The silly function does nothing except get "decorated." classmethod
determines the form of the first argument (class, object, or
other). signature changes the call behavior, asserting the types
passed to and returned from the function. Finally, transactional
causes boilerplate code to be executed before and after the function
body, ensuring that either all changes to database are applied, or
none are. Seeing as this function does nothing, this is trivial :).
"""
@classmethod
# PLH 20040806112957: added new decorator here
# PLH 20040806130023: also changed last value
@signature( None, a=int, b=float, c=dict)
@transactional( database)
pass


While I find merit in your idea, it's not entirely fair to discard
the @ syntax because it *can* be written the way you showed, but then
not to perform the same analysis on your own idea.

To be entirely fair, I'm not sure that *any* of the proposed syntaxes
cannot be written in such a way that they get buggered up by intervening
whitespace and comments... nor should this be a sole reason for
discarding any one.

-Peter
Jul 18 '05 #11
David Fraser wrote:
I like this idea. What about using the list syntax instead of the @
syntax:

[static, synchronized, types(int, int), returns(None) ]:
def foo():
pass
<rant level="hysterical">
No, no, NO! Lists are value expressions: not statements, not
declarators, and most certainly not suites!!!
</rant>

Sorry, just had to get that out of my system... :)

Seriously, though, one problem I see is that this can get obfuscative
really fast as the number or complexity of decorators grows:

[static,
synchronized,
types(int, int),
returns(None),
yet,
more,
decorators,
go,
here,
making(this),
quite,
the( (pain, to, read, past))
]:
def foo():
pass

By the time I've read all of that, I've likely forgotten what it was I
was looking for in the first place. Of course, the @ syntax as it stands
has the same problem, but at least it doesn't introduce spurious
indentation in the process.
This would then take away the argument against a valid list before a
def being valid python but not previously having any effect...
Right. At the expense of a grammar that is nonsensical when viewed in
the context of how those symbols work elsewhere in the language. Here we
have a list (okay), containing a bunch of function names (okay), which
get called via side-effect on something not explicitly indicated
(er...), and starts a block of code (say what???).

The (){}[] symbols all already *mean* something in python (often more
than one thing, actually). The @ doesn't mean anything yet, so it is a
perfect candidate for a completely new concept such as this. I just
think that they put it in the wrong spot.
declare [static, synchronized, types(int, int), returns(None)]:
def foo():
pass
def bar():
pass


People keep suggesting this one, and I just don't see it. Yes, it's
shorter (marginally, sometimes). But is it really clearer? I don't think
so. Now, instead of just having to look at the preceding few lines to
figure out what decorators are being used, you have to look up an
arbitrary number of lines. Not fun when one's functions start getting
real-world sized.

I understand the desire to reduce the redundancy, but even this small
example shows a fundamental problem with this approach. In all but the
most simple cases, most functions will end up with *different* sets of
decorators. Case in point: both foo and bar above take (int, int) and
return None. Such parity rarely survives in the wild. This leaves us
with even more of a mess:

declare [static, synchronized]:
declare [returns(None)]:
declare [types(int)]:
def foo(a):
pass
declare [types(int, int)]:
def bar(a, b):
pass
declare [returns(int)]:
def baz():
pass

I *shudder* to think of trying to sort this out when these functions
contain real code.

(FYI: None of this is directed at you, personally. Your post just
happened to be the first post I found suggesting this kind of syntax.)

-- Mark
Jul 18 '05 #12
David Fraser wrote:
John Roth wrote:
"daishi" <go****@daishi.fastmail.fm> wrote in message
news:d2**************************@posting.google.c om...
For what it's worth:

As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another.


Examples:

try - except - finally
if - elif - else
while - else


I think he mean two consecutive lines of python code with the same
indentation.


That's how I took it. From another angle, each of the clauses in
try/except/finally et al start a suite (i.e., end in ':'); @dec does
not. Except for the funny symbol, it looks just like any other
statement--but it sure doesn't act like one.

-- Mark
Jul 18 '05 #13

"David Fraser" <da****@sjsoft.com> wrote in message
news:cf**********@ctb-nnrp2.saix.net...
John Roth wrote:

"daishi" <go****@daishi.fastmail.fm> wrote in message
news:d2**************************@posting.google.c om...
As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another.
Examples:

try - except - finally
if - elif - else
while - else


I think he mean two consecutive lines of python code with the same
indentation.


And the same examples apply:

if like(atdeco): print 'hooray'
else: print 'boo'

Terry J. Reedy


Jul 18 '05 #14
Peter Hansen wrote:
Mark Bottjer wrote:

Mark, would your example still be acceptable to you if someone wrote
it like this?:
def sillyFunction( a, b, c):
"""\
The silly function does nothing except get "decorated." classmethod
determines the form of the first argument (class, object, or
other). signature changes the call behavior, asserting the types
passed to and returned from the function. Finally, transactional
causes boilerplate code to be executed before and after the function
body, ensuring that either all changes to database are applied, or
none are. Seeing as this function does nothing, this is trivial :).
"""
@classmethod

# PLH 20040806112957: added new decorator here
# PLH 20040806130023: also changed last value @signature(
None, a=int, b=float, c=dict)
@transactional( database)
pass


FWIW, I considered adding this case, but thought the post was long
enough already. And I knew someone would bring me to task on it in short
order anyway. :)

Of course it is still hard to read, but I personally find it easier than
the prefix syntax for one main reason: the decorators are confined
inside the function they modify. If the language were to state (for
example) that all decorators are to appear between the def line and the
optional docstring, than it becomes easy (easier, anyway) to parse, and
for the programmer to navigate: find function def; start looking for
meta stuff; stop looking at the first non-meta statement. No look-ahead
is required, and no buffering for a declaration not yet started.
While I find merit in your idea, it's not entirely fair to discard
the @ syntax because it *can* be written the way you showed, but then
not to perform the same analysis on your own idea.
I wasn't attempting to discard it. I was attempting to show a border
case I had not seen discussed anywhere (as others have done with the def
foo (ARGS) [DECS]: variants). To that end, I tried to show just how bad
it could be. To make sure it had been considered was the sole intent.
To be entirely fair, I'm not sure that *any* of the proposed syntaxes
cannot be written in such a way that they get buggered up by intervening
whitespace and comments... nor should this be a sole reason for
discarding any one.


Agreed. I *personally* find it easier to understand code with the
decorators infixed than with them prefixed. To me, knowing that
everything I want to know about a function is somewhere *in* that
function, as opposed to somewhere *near* it, is quite a powerful aide to
understanding. YMMV.

-- Mark
Jul 18 '05 #15
"Terry Reedy" <tj*****@udel.edu> wrote in message news:<ma**************************************@pyt hon.org>...
And the same examples apply:

if like(atdeco): print 'hooray'
else: print 'boo'

Terry J. Reedy


I apologize if I've phrased things poorly/imprecisely,
but in large part your example exemplifies the point that
I was trying make in my previous message: decorators seem
like they belong in or are themselves compound statements.
The current proposed formatting seems to me like:

else print 'boo'
if like(atdeco): print 'hooray'
Jul 18 '05 #16
I do not know much about decorators yet,
but how about a decorator module for
default stuff e.g. synchronized etc.?
Does this make sense?

Ciao,
Dominic
Jul 18 '05 #17
Neil Hodgson wrote:
daishi:
As far as I know, the proposed @decorator syntax will be the first
time that two logical lines of python with the same indentation will
not be independent of one another. Previously, when looking at:

some_python(code)
and_some_more = stuff

there was no need to look at the the first line in order to know what
the second line meant/did (and vice versa).


Much of the time, consecutive lines with the same indentation are highly
dependent with earlier lines modifying the behaviour of successor lines:

global x
x = 9


Poor example. They are visually tied together in that they both mention
the variable x. '@decorator's do not mention the function they affect.

--
Hallvard
Jul 18 '05 #18

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...
8
by: Michele Simionato | last post by:
Decorators can generate endless debate about syntax, but can also be put to better use ;) Actually I was waiting for decorators to play a few tricks that were syntactically too ugly to be even...
4
by: RebelGeekz | last post by:
Just my humble opinion: def bar(low,high): meta: accepts(int,int) returns(float) #more code Use a metadata section, no need to introduce new messy symbols, or mangling our beloved visual...
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...
13
by: km | last post by:
Hi all, was going thru the new features introduced into python2.4 version. i was stuck with 'decorators' - can someone explain me the need of such a thing called decorators ? tia KM
11
by: Helmut Jarausch | last post by:
Hi, are decorators more than just syntactic sugar in python 2.x and what about python 3k ? How can I find out the predefined decorators? Many thanks for your help, Helmut Jarausch
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
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.