473,563 Members | 2,867 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

@decorator syntax is sugar, but for what exactly?

ISTM that
@limited_expres sion_producing_ function
@another
def func(): pass

is syntactic sugar for creating a hidden list of functions. (Using '|' in place of '@'
doesn't change the picture much (except for people whose tools depend on '@' ;-)).

I.e., (not having the source or time to delve) the apparent semantics of the above
is something roughly like

__funclist__ = []
__funclist__.ap pend(limited_ex pression_produc ing_function)
__funclist__.ap pend(another)
def func():pass
while __funclist__: func = __funclist__.po p()(func)
del __funclist__

Is this a special case of a more general idea? E.g., could it apply to
right after ANY next name is bound, in general, not just a name bound by def?

thus (untested)

def censor(cls):
cls.__repr__ = lambda self: '<CENSORED>'
return cls
...
@censor
class C(object): pass

could have the expected effect (after metaclass effects, if any, presumably, BTW)
(note that censor could instead e.g. wrap selected methods or add class variable data etc.,
though IIRC __metaclass__ can create some things that are read-only later)

This is still very narrowly defined by prefix context. Is this context also
a special case default of something more general? IOW the default choice for
namespace is the lexically enclosing one. What about, e.g., being able to specify
decoration in one place at the top of a module and decorate (in the same way, using
the same function list) all methods of a specified (by name) list of classes?

I.e., a more general control over what to do when what names are bound in what namespace
could be envisaged. This begins to feel like event-driven processing. Could @deco1 @deco2
be sugar for the special case (don't take this literally, just illustrating semantics ;-)

when(event='nex t_binding', namespace='imme diate', symbols='any', funclist=(deco1 ,deco2))
def foo(): pass

of something general that could also include other and possibly repeated events like on completion
of an arg list for a particular function or method being called or any rebinding of particular
symbols in a specified namespace (not just the immediate one), e.g., for debugging or profiling etc.

Since I am copying this to python-dev, I'll re-ask whether @decorator has any peculiar
thread safety pitfalls that should be warned against, just in case.

Please take this as a probe into the intended semantics, not as a proposal for any particular
functionality ;-)

Regards,
Bengt Richter
Jul 18 '05 #1
37 2581
On Sat, Aug 07, 2004 at 23:50:47 +0000, Bengt Richter wrote:

The code:
@limited_expres sion_producing_ function
@another
def func(): pass


is equivalent to:

def func(): pass
func = limited_express ion_producing_f unction(another (func))
--
mithrandi, i Ainil en-Balandor, a faer Ambar

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFBFW0opNu XDQIV94oRAljjAJ 0aJsggvp2vEVeCg BCapiTgbSb+gQCf TWTF
OUghKvwWu/GZ7JMTBf9ppzI=
=BwLb
-----END PGP SIGNATURE-----

Jul 18 '05 #2
I have read a few Python blogs and not a one is taking the decorator syntax
in a good way.

The Python of 1.5.2 simplicity will be long gone.
Jul 18 '05 #3
Robert wrote:
I have read a few Python blogs and not a one is taking the decorator syntax
in a good way. classmethod and staticmethod were introduced some time ago, to provide
a mechanism for getting to such effects. At the time there was no clear
syntax to use that "felt right." In the meantime people have used these
features to good effect despite the clunky way you used them. At this
point there would probably be a small riot (or at least a large whine)
if these two were removed.

When I first came to Python, I was delighted to see that Idle gave me
function clues not only for the system code, but for the code _I_ wrote.
Since it takes discipline to write comments that may never be read, it
was delightful to finally see an immediate reward for doing a little
documentation work -- I could help myself on my own utility functions.

However, there are more and more uses of the docstring for things other
than documentation. At this point, I see more and more docstring uses
as "cybercrud" -- The only easy function annotation is the docstring so
all ambitious program annotation schemes use it. There are good reasons
for wanting to be able to annotate functions and methods, but precious
few good reasons for polluting the document strings in order to do so.

Decorators are a way out. I don't know about the syntax, it looked bad
when I first saw it, but like some others, I welcome _almost_any_syn tax_
for decorators. Not, so much, because I want to use decorators. I just
want others to stop using docstrings for non-documentation purposes. In
fact, I don't even really like the unittest convention of using method
names to identify test methods -- I prefer a language where the what you
call a thing does not affect how it works.
The Python of 1.5.2 simplicity will be long gone.

Well, there was a lot to like even then, but I'd hate to give up what
we now have -- you can do things in a much more functional style now,
with nested scopes. Would you really like to go back to three-strikes
and you are out symbol lookup? This language has changed at a good
pace, and (quite surprisingly) slowly to a more consistent model (a
major coup in language design). The aesthetic that has driven that
change suggests that this might be the right syntax for declarators.
I know I wouldn't have done nearly as well as Guido and gang at making
language decisions.

I certainly intend to take this alpha period as a time to experiment
with decorators and see if the syntax grows on me; I suggest others
do the same. Give it its best chance; you may become a fan. Several
of the py-dev people claim they have already gone from distaste to
support.

--
-Scott David Daniels
Sc***********@A cm.Org
Jul 18 '05 #4
On Sat, 7 Aug 2004 20:24:45 -0400, Robert <ca*****@linuxm ail.org> wrote:
I have read a few Python blogs and not a one is taking the decorator syntax
in a good way.
Most of the posts I read seemed to be from people having a visceral
response to the syntax. I think it's fair to say that many of the people
complaining about the syntax have not actually downloaded the alpha
and tried out the new decorators in actual code.
The Python of 1.5.2 simplicity will be long gone.


The "Python of 1.5.2 simplicitly" is long, long gone. I don't agree that
newer Python's are somehow worse because new things have been
added. A short list:

new style classes
foo(*arg, **kwarg)
iterators
generators
list comprehensions

In many cases, these new features actually lead to smaller, simpler
code. I challenge _anyone_ to tell me that
apply(func, args, kwargs)
is better than
func(*args, **kwargs)
Jul 18 '05 #5
Anthony Baxter wrote:
The "Python of 1.5.2 simplicitly" is long, long gone. I don't agree that
newer Python's are somehow worse because new things have been
added. A short list:

new style classes
foo(*arg, **kwarg)
iterators
generators
list comprehensions


My favourite one: string methods.

Regards,
Martin
Jul 18 '05 #6
On Sun, 8 Aug 2004 18:24:58 +1000,
Anthony Baxter <an***********@ gmail.com> wrote:
In many cases, these new features actually lead to smaller, simpler
code. I challenge _anyone_ to tell me that
apply(func, args, kwargs)
is better than
func(*args, **kwargs)


Okay, I will. The old way is better than the new way.

Explicit is better than implicit, after all.

Given your second example, is func the name of a function or an object
that references a function? Can I grep my source code to find a
function named func? (Okay, I'll find the variable named func, so at
least I'll have some clue as to what's going on.) Is there a "from
module import func" statement in sight? What happens when I look up
"func" in the Python documentation to see if it's a built in name?

C did the same thing recently.

Old C: (*f)( argument );

New C: f( argument );

With the old syntax, I knew immediately that f was a pointer to a
function and that the function to which it pointed was being called
indirectly. With the new one, I have to track down a definition or
declaration of f to see that. Yes, this used to be much more important
than it is now. Perhaps my years of assembly language applications in
extremely tight situations and are showing through.

Yes, I know that Python functions are first class objects and should be
treated as such. Yes, I know that Python is not C. But with function
application being built right into the syntax of the language (i.e., an
identifyer followed by a parenthesized argument list), I would like to
see a visual difference between calling a named function vs. calling a
function indirectly through some sort of reference. Yes, I also know
that in most cases "it's obvious from context," but with the old way, it
was obvious without any context and evident to the simplest of automated
tools.

That all said, when I use the new syntax (okay, you got me, I do use the
new syntax on occasion), I always leave a comment nearby to explain
what's going on. I agree: the *code* is smaller and arguably simpler,
but the *program* and the *software* are not.

Regards,
Dan

--
Dan Sommers
<http://www.tombstoneze ro.net/dan/>
Never play leapfrog with a unicorn.
Jul 18 '05 #7
Scott David Daniels wrote:
...
classmethod and staticmethod were introduced some time ago, to provide
a mechanism for getting to such effects. At the time there was no clear
syntax to use that "felt right." In the meantime people have used these
features to good effect despite the clunky way you used them. At this
point there would probably be a small riot (or at least a large whine)
if these two were removed.
...


The "property" call resembles both classmethod, staticmethod and
instancemethod, but cannot be eliminated using the new function
decorator syntax, because of its m:1 nature - one property binds
together a getter, a setter etc., where staticmethod etc. change the
status of one function in one way.

So, if the problem is to rid class definitions of bizarre function
calls, stuck in the middle of nowhere, that actually add to the
structure of the class (and which other OO languages solve by legitimate
syntax), I am dissapointed to observe that functuion decorators do not
do a complete job after all.

Talking about properties, I like the C# way of defining them, which is
straightforward and readable. The property begins like a method, but has
no argument list and includes a getter function with no arguments and a
setter function with one argument. Adapted to Python, it would look
something like:

class hasProperty:
def __init__(self,a Property='')
self.aProperty = aProperty
def AProperty:
def get(self):
return self.aProperty
def set(self,value) :
self.aProperty = value
obj = hasProperty()
obj.AProperty = 'test'
print obj.AProperty
Jul 18 '05 #8
Dan Sommers <me@privacy.net > wrote in
news:m2******** ****@unique.ful ly.qualified.do main.name.yeah. right:
On Sun, 8 Aug 2004 18:24:58 +1000,
Anthony Baxter <an***********@ gmail.com> wrote:
In many cases, these new features actually lead to smaller, simpler
code. I challenge _anyone_ to tell me that
apply(func, args, kwargs)
is better than
func(*args, **kwargs)
Okay, I will. The old way is better than the new way.

Explicit is better than implicit, after all.

Given your second example, is func the name of a function or an object
that references a function? Can I grep my source code to find a
function named func? (Okay, I'll find the variable named func, so at
least I'll have some clue as to what's going on.) Is there a "from
module import func" statement in sight? What happens when I look up
"func" in the Python documentation to see if it's a built in name?


Why do you ask this about the second form only? func is a name that
references a function in both cases. It doesn't matter whether that name
was assigned directly with a def statement, or is the result of a
subsequent binding.

C did the same thing recently.

Old C: (*f)( argument );

New C: f( argument );

With the old syntax, I knew immediately that f was a pointer to a
function and that the function to which it pointed was being called
indirectly. With the new one, I have to track down a definition or
declaration of f to see that.


For 'recently' read 1987. In fact most C compilers probably implemented
this feature before the ISO standard came out, but it was a feature of the
first standardised version of C. I remember around that time being
extremely glad that I could finally omit those extraneous parentheses.
Jul 18 '05 #9
Anthony Baxter <an***********@ gmail.com> wrote:
The "Python of 1.5.2 simplicitly" is long, long gone. I don't agree that
newer Python's are somehow worse because new things have been
added. A short list:

new style classes
foo(*arg, **kwarg)
iterators
generators
list comprehensions


Perhaps I'm just a luddite, but I don't actually use most of those
features. I have started playing around with iterators/generators, and
find them very cool.

The single biggest improvement I see in the language since 1.5.2 is
string methods! After that, maybe augmented assignments (or whatever
you call them; the ability to write "x += 1").

Most of the big improvements I've seen are in the library. When did
unitest get added? I can't live without unittest. I like the logging
module, even if I think it's about twice as complicated as it should be.

A lot of my own personal growth in how I use the language is discovering
modules which, while not new to the language, are new to me because I'd
never noticed them before.

Speaking of libraries, Dan Bishop posted some interesting example of
@memoize and @printreturns utility wrappers. This leads me to think
that a good way to leverage the idea of decorators would be a module of
common utility functions which could be used as decorators by anybody.
I'll call the module martha (since it supplies things used for
decorating). Does the proposed mechanism support something like (to use
one of Dan's exmaples, written with two different syntaxen):

import martha

@martha.memoize
def fibonacci(n):
if n in (0, 1):
return n
return fibonacci(n - 1) + fibonacci(n - 2)

def fibonacci(n):
@martha.memoize
if n in (0, 1):
return n
return fibonacci(n - 1) + fibonacci(n - 2)

Some of these things might even be usefully re-written in C for improved
performance.

I'm even wondering if somehow decorators could be used for i18n? The
obvious problem there, is print is a statement not a function, and you
can't decorate statements (or can you???).
Jul 18 '05 #10

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

Similar topics

14
2291
by: Sandy Norton | last post by:
If we are going to be stuck with @decorators for 2.4, then how about using blocks and indentation to elminate repetition and increase readability: Example 1 --------- class Klass: def __init__(self, name):
23
1910
by: C. Barnes | last post by:
I vote for def f(): (body of function) This is backwards compatible (Python <= 2.3 raise SyntaxError), and looks much nicer than @. The only problem is that you can't one-line a decorated function. You can't do that with
1
1289
by: Sakesun Roykiattisak | last post by:
I have developed a framework to ease my database programming job, called "DescribedData Framework" which use inspection on function/method parameter-name to simplify my code. for example: -------- connection = dbi.connect('database-connection-string') cursor = connection.cursor() cursor.execute('select TITLE, NAME, AGE from PEOPLE')
24
2035
by: Steven Bethard | last post by:
I think one of the biggest reasons we're having such problems coming to any agreement on decorator syntax is that each proposal makes a number of syntax decisions, not just one. For decorators, I see the following decisions that must be made: 1) Indicator Proposals differ on how some sort of indicator of "decoratorhood" is use. These...
11
1619
by: Ville Vainio | last post by:
It might just be that @decorator might not be all that bad. When you look at code that uses it it's not that ugly after all. A lot of the furor about this is probably because it happened so quicly. The situation might have been different if we had seen a pronouncement a week before, in the vein of "I have chosen this syntax - it will go in...
7
1576
by: Steven Bethard | last post by:
So here's the state of the decorator debate as I see it: *** Location GvR pretty strongly wants decorators before the function: http://mail.python.org/pipermail/python-dev/2004-August/047112.html http://mail.python.org/pipermail/python-dev/2004-August/047279.html
41
2829
by: John Marshall | last post by:
How about the following, which I am almost positive has not been suggested: ----- class Klass: def __init__(self, name): self.name = name deco meth0: staticmethod def meth0(x):
12
1524
by: Steven Bethard | last post by:
The poll, as stated, asked voters to vote for the syntax suggestion they liked the /most/. Some of the conclusions people are trying to draw from it are what syntaxes people liked the /least/. This is probably not the right conclusion to be drawing from the poll that was given. It is, however, the kind of conclusion I think we'd like to...
99
4571
by: Paul McGuire | last post by:
There are a number of messages on the python-dev mail list that indicate that Guido is looking for some concensus to come from this list as to what *one* alternative syntax for decorators we would like him to consider in place of the @ syntax that is currently in 2.4a2. I think special thanks are due to: - Anthony Baxter for his continuing...
0
7665
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7583
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7888
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7642
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7950
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5484
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5213
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3643
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3626
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.