473,473 Members | 2,236 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

__metaclass__ and __author__ are already decorators

Thinking about decorators, and looking at what we are already doing in
our Python code, it seems that __metaclass__, __author__, __version__,
etc. are all examples of decorators. So we already have a decorator
syntax. What is the compelling reason to invent a new one? And if we
do, what's to become of the old one?

Here's my take on this. We have two kinds of decorators: those that
are informational only (like __author__ and __version__), and those
which have side-effects, i.e. those that actually *do* something (like
__metaclass__).

class Foo:
""" This describes the Foo class as normal. """
__metaclass__ = M
__author__ = 'Paul Morrow'
__version__ = '0.1'
__automethods__ = True
def baz(self, a, b):
""" This describes the baz method. """
__synchronized__ = True
__returns__ = None
__author__ = 'Neville Shunt'
# body of baz goes here...

There, that looks pretty clear and pythonic. Now how to define the
decorators.

def metaclass(decoratedClass, subType):
""" This describes the 'metaclass' decorator. """
__decorator__ = True
__version__ = '1.9'
# perform the metaclass operation on decoratedClass
def synchronized(decoratedFunc, trueOrFalse):
""" This describes the 'synchronized' decorator. """
__decorator__ = True
__author__ = 'Martin Curry'
__version__ = '0.5'
# perform the synchronized operation on decoratedClass
def returns(decoratedFunc, *args):
"""Docstring for 'returns' decorator."""
__decorator__ = True
# body of decorator goes here
Each decorator function receives the class|function|method being
decorated as the first parameter of the function (e.g. decoratedClass
and decoratedFunc above). The remaining parameters are the values
assigned to the __xxx__ variable in the definition of the decorated
function.

So, in the above example, when the 'returns' decorator function is
called to decorate the 'baz' method, decoratedFunc would recieve the baz
object and args[0] would be set to None (because of the statement
"__returns__ = None" in the definition of baz).

For a function to be used as a decorator function, it must be decorated
as such, by setting its __decorator__ attribute to True.

Does this handle enough of the decorator concerns?

Paul

Jul 18 '05 #1
10 2189
Paul Morrow wrote:
Thinking about decorators, and looking at what we are already doing in
our Python code, it seems that __metaclass__, __author__, __version__,
etc. are all examples of decorators. So we already have a decorator
syntax. What is the compelling reason to invent a new one? And if we
do, what's to become of the old one?
<snip>


I've thought about something along the lines of your suggestion before,
but it doesn't seem very Pythonic to assign special meaning to function
variables with special names to me. It's essentially a new syntax, but
disguised as an old syntax with an entirely different meaning.
Jul 18 '05 #2
Leif K-Brooks wrote:
Paul Morrow wrote:
Thinking about decorators, and looking at what we are already doing in
our Python code, it seems that __metaclass__, __author__, __version__,
etc. are all examples of decorators. So we already have a decorator
syntax. What is the compelling reason to invent a new one? And if we
do, what's to become of the old one?
<snip>

I've thought about something along the lines of your suggestion before,
but it doesn't seem very Pythonic to assign special meaning to function
variables with special names to me. It's essentially a new syntax, but
disguised as an old syntax with an entirely different meaning.


We just need to stop thinking of them as local function variables.
Instead we should think of __xxx__ attributes as describing the function
itself (i.e. as a decorator would), as I believe that is almost always
the author's intention when he/she uses such names inside of a
function/method definition. He wants to say something about the
function (who wrote it, it's version, etc.), and is probably sad that it
has the side-effect of creating a local variable. So it probably
shouldn't have that side-effect anymore. It should create a function
attribute instead (not to be confused with a local variable).

For classes, it's much easier to accept this new way of looking at
__xxx__ attributes because it's consistent with our intention behind
them (as names for metadata rather than normal, inheritable class
attributes).

Jul 18 '05 #3
Paul Morrow wrote:
We just need to stop thinking of them as local function variables.
Instead we should think of __xxx__ attributes as describing the function
itself (i.e. as a decorator would), as I believe that is almost always
the author's intention when he/she uses such names inside of a
function/method definition. He wants to say something about the
function (who wrote it, it's version, etc.), and is probably sad that it
has the side-effect of creating a local variable. So it probably
shouldn't have that side-effect anymore. It should create a function
attribute instead (not to be confused with a local variable).


Which is, like I said, assigning new meaning to an old syntax. That
seems confusing to me; why not just create a new syntax?
Jul 18 '05 #4
Leif K-Brooks wrote:
Paul Morrow wrote:
We just need to stop thinking of them as local function variables.
Instead we should think of __xxx__ attributes as describing the
function itself (i.e. as a decorator would), as I believe that is
almost always the author's intention when he/she uses such names
inside of a function/method definition. He wants to say something
about the function (who wrote it, it's version, etc.), and is probably
sad that it has the side-effect of creating a local variable. So it
probably shouldn't have that side-effect anymore. It should create a
function attribute instead (not to be confused with a local variable).

Which is, like I said, assigning new meaning to an old syntax. That
seems confusing to me; why not just create a new syntax?


Because it's not needed and would make the language more complex.

And I don't agree that this would be assigning new 'meaning' to an old
syntax. When a programmer creates a __xxx__ class attribute, he is not
trying to create a normal 'class' attribute --- one the is inherited by
instances of the class or that holds part of the 'state' of the class.
Instead, he is trying to make a meta statement about the class (who
wrote it, what happens during instance initialization, etc.). In that
sense, the meaning associated with defining __xxx__ attributes would
stay the same.

Jul 18 '05 #5
Paul Morrow wrote:
And I don't agree that this would be assigning new 'meaning' to an old
syntax. When a programmer creates a __xxx__ class attribute, he is not
trying to create a normal 'class' attribute --- one the is inherited by
instances of the class or that holds part of the 'state' of the class.
Instead, he is trying to make a meta statement about the class (who
wrote it, what happens during instance initialization, etc.). In that
sense, the meaning associated with defining __xxx__ attributes would
stay the same.


If we were talking about something like this:

def foo(self):
pass
foo.__author__ = "Leif K-Brooks"

then you would be correct. But when syntax normally used for assigning
to a variable magically assigns to an attribute if the variable name
starts and ends with "__", then it's an existing syntax (variable
assignment) being used for something new (attribute assignment). Why
should this:

def foo(self):
bar = 42

mean anything different from this?

def foo(self):
__bar__ = 42
Jul 18 '05 #6
Leif K-Brooks wrote:
Paul Morrow wrote:
And I don't agree that this would be assigning new 'meaning' to an old
syntax. When a programmer creates a __xxx__ class attribute, he is
not trying to create a normal 'class' attribute --- one the is
inherited by instances of the class or that holds part of the 'state'
of the class. Instead, he is trying to make a meta statement about the
class (who wrote it, what happens during instance initialization,
etc.). In that sense, the meaning associated with defining __xxx__
attributes would stay the same.

If we were talking about something like this:

def foo(self):
pass
foo.__author__ = "Leif K-Brooks"

then you would be correct. But when syntax normally used for assigning
to a variable magically assigns to an attribute if the variable name
starts and ends with "__", then it's an existing syntax (variable
assignment) being used for something new (attribute assignment). Why
should this:

def foo(self):
bar = 42

mean anything different from this?

def foo(self):
__bar__ = 42


Because the intent of the two assignments is quite different. Yes,
their syntactic structure is similar, and what happens after they
execute is similar, but the 'kind' of information the programmer is
trying to represent is very different in the two cases.

In the first example, the programmer intends for bar to be a local
variable, used in some way by foo. In the second example, the
programmer most definitely does *not* intend for __bar__ to be used by
foo --- instead he is simply providing information *about* foo. This
better illustrates the difference.

def circumference(diameter):
__author__ = 'Paul Morrow'
__version__ = '0.1'
pi = 3.14
return pi * diameter

So when we define an __xxx__ attribute inside of a function, we are
trying to make a statement about the function --- we are not trying to
create a local variable. Therefore the Python system shouldn't create a
local variable in this case; it should create a function variable
instead (IMO).

Jul 18 '05 #7
Paul Morrow wrote:
So when we define an __xxx__ attribute inside of a function, we are
trying to make a statement about the function --- we are not trying to
create a local variable. Therefore the Python system shouldn't create a
local variable in this case; it should create a function variable
instead (IMO).


How do you think a newbie will react to magic behavior like that from
the assignment operator based entirely on the name being assigned to?
Jul 18 '05 #8
Leif K-Brooks wrote:
Paul Morrow wrote:
So when we define an __xxx__ attribute inside of a function, we are
trying to make a statement about the function --- we are not trying to
create a local variable. Therefore the Python system shouldn't create
a local variable in this case; it should create a function variable
instead (IMO).

How do you think a newbie will react to magic behavior like that from
the assignment operator based entirely on the name being assigned to?


We must emphasize that they are assigning to a 'magic' variable, as all
__xxx__ attributes are supposed to be. One must be careful with magic :-)
Jul 18 '05 #9
Paul Morrow wrote:
Leif K-Brooks wrote:
Paul Morrow wrote:
So when we define an __xxx__ attribute inside of a function, we are
trying to make a statement about the function --- we are not trying
to create a local variable. Therefore the Python system shouldn't
create a local variable in this case; it should create a function
variable instead (IMO).


How do you think a newbie will react to magic behavior like that from
the assignment operator based entirely on the name being assigned to?


We must emphasize that they are assigning to a 'magic' variable, as all
__xxx__ attributes are supposed to be. One must be careful with magic :-)


I'm starting to reconsider whether I like your proposal. My first
reaction was against it, since it seems like Perl-style magic behavior,
but now I'm not sure. It definitely is magic, but its purpose seems much
more clear than a lot of the other decorator proposals; that's what
Python is all about.
Jul 18 '05 #10
Leif K-Brooks <eu*****@ecritters.biz> writes:
Which is, like I said, assigning new meaning to an old syntax. That
seems confusing to me; why not just create a new syntax?


One could argue for the other way around as well: __metaclass__ et al
are class variables assigned special meaning. If new syntax for
decorators is important, why introduce the __metaclass__ "decorator"
before the new syntax is present?
Jul 18 '05 #11

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

Similar topics

4
by: David M. Wilson | last post by:
Hi there, I've been sitting on the __metaclass__ feature for about 2 weeks now, and haven't really got that far with it. It looks like a very powerful tool, and I think I have even already...
17
by: daishi | last post by:
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....
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...
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...
12
by: David Keeney | last post by:
I see this set (or similar) of variables in various modules I read. They are found near the top of each module file, outside of any class or function definitions. " __author__ = "Software...
9
by: Joel Hedlund | last post by:
Hi! I need some input on my use of metaclasses since I'm not sure I'm using them in a pythonic and graceful manner. I'm very grateful for any tips, pointers and RTFMs I can get from you guys. ...
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...
3
by: Mark Shroyer | last post by:
I guess this sort of falls under the "shameless plug" category, but here it is: Recently I used a custom metaclass in a Python program I've been working on, and I ended up doing a sort of write-up...
1
by: Wouter DW | last post by:
I read the article on http://www.python.org/download/releases/2.2/descrintro/#metaclasses and started using autoprop. But now I have a problem I can't seem to solve myself. class autoprop(type):...
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
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...
1
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...
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: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
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.