AntiDecorator metaclass

P

Paul Morrow

One of the beautiful things about Python is its clear, minimal syntax.
So we must resist adding new syntax to the language, especially where
there is a reasonable alternative.

I believe that Stefen Eischet's suggestion for automatically determining
a method's type (class/instance/static) from the name of its first
formal parameter is a reasonable alternative to any/all of the decorator
syntax proposals.

Just as the Python system relies on indentation conventions to denote
the programmer's intended block structure, it could just as well rely on
parameter naming conventions to denote method types. And as long as
these conventions feel natural to the programmer, the language retains
its beauty.

So here is a metaclass that illustrates (what I believe is) the
essential idea behind Stefen's suggestion. See the docstring and
footnotes for a description of what it does.

##################################################################
class AntiDecorator(type):
""" Metaclass that protests against decorator syntax :)

This metaclass infers a method's method type (instance, class,
or static) from the name of its first formal parameter, then
makes the necessary Python declaration.

* If the 1st parm's name is 'self', then the method is
an instance method.

* If the 1st parm's name is 'cls' or 'klass', then the
method is a class method.

* All other methods are static methods.

-------------------------------------------------
The essence of this technique was suggested by
Stefan Eischet on the comp.lang.python newsgroup.
-------------------------------------------------

This is freeware, no warranties, etc...

"""
__author__ = 'Paul Morrow <[email protected]>'
__credits__ = 'Stefen Eischet <[email protected]>'
__date__ = '13 Aug 04'
__version__ = '0.1'

def __new__(cls, clsName, bases, dict):
import inspect, types
for fName in dict.keys():
f = dict[fName] # 1.
if type(f) is types.FunctionType: # 2.
parmNames = inspect.getargspec(f)[0] # 3.
if parmNames: # 4.
if parmNames[0] in ('cls', 'klass'): # 5.
dict[fName] = classmethod(f)
elif parmNames[0] == 'self': # 6.
pass
else: # 7.
dict[fName] = staticmethod(f)
else: # 8.
dict[fName] = staticmethod(f)
return type.__new__(cls, clsName, bases, dict)
"""Footnotes:
1. Bind f to an attribute of the class (cls).
2. Only work this magic on functions.
3. Get the function's formal parameter names.
4. If it has formal parameters, we'll use them
to determine what kind of function it is.
5. It's a class method if its first formal
parameter is 'cls' or 'klass'.
6. It's an instance method (default) if its first
formal parm is 'self'
7. It's a static method if it's not a class method
or instance method.
8. No formal parameters, so it's a static method.
"""

class Object(object):
""" Uses AntiDecorator metaclass to infer method type. """
__metaclass__ = AntiDecorator

if __name__ == '__main__':
class Foo(Object):
def imethod(self, parm):
print "I'm an instance method: %s." % parm
def cmethod(cls, parm):
n = cls.__name__
print "I'm a class method (of %s): %s." % (n, parm)
def smethod(parm):
print "I'm a static method: %s." % parm

Foo().imethod('alpha')
Foo.smethod('beta')
Foo.cmethod('gamma')
##################################################################
 
C

Christophe Cavalaria

Paul said:
One of the beautiful things about Python is its clear, minimal syntax.
So we must resist adding new syntax to the language, especially where
there is a reasonable alternative.

I believe that Stefen Eischet's suggestion for automatically determining
a method's type (class/instance/static) from the name of its first
formal parameter is a reasonable alternative to any/all of the decorator
syntax proposals.

Here is another one that forgot that decorators aren't limited to
classmethod and staticmethod. Therefore, that proposal alone isn't an
alternative to any other syntax.

If you want to say that decorators should be limited to classmethod and
staticmethod, say it and give us a good reason, a very very good reason.
 
P

Paul Morrow

Christophe said:
Paul Morrow wrote:




Here is another one that forgot that decorators aren't limited to
classmethod and staticmethod. Therefore, that proposal alone isn't an
alternative to any other syntax.

If you want to say that decorators should be limited to classmethod and
staticmethod, say it and give us a good reason, a very very good reason.

No I don't want to say that. I want to say that decorators should keep
their nose out of the classmethod/staticmethod business. There's a
perfectly good *no-extra-syntax-required* way to do that, thru the
leveraging of conventions that most developers use already (give or take
the spelling of the class parameter). The code remains readable,
intuitive, obvious, unintimidating. And it makes the problem space that
decorators address smaller (as it becomes everything you want decorators
to do minus the classmethod/staticmethod stuff), which might give rise
to a better, less objectionable solution.
 
A

Anthony Baxter

No I don't want to say that. I want to say that decorators should keep
their nose out of the classmethod/staticmethod business.

So what's the point of this, then? You say it's an "anti-decorator" metaclass.
It's not. It's simply a way to automagically invoke a couple of standard
decorators from a metaclass, based on people following a convention.

It does little or nothing to address many of the other requirements for
decorators, is brittle (see my previous post on the subject) and relies on
something that is merely a convention, and deliberately so.
And it makes the problem space that
decorators address smaller (as it becomes everything you want decorators
to do minus the classmethod/staticmethod stuff), which might give rise
to a better, less objectionable solution.

I fail to see how your hack, which merely removes two of the most trivial
examples of decorator use, addresses anything in the general case.

As far as a "better, less objectionable solution" - as I've said time and time
again, this subject has had 2+ years of discussion. Do you honestly
expect that 2 or 3 more weeks here or there is going to produce some
blinding flash of insight? I'd love it to be true, but really, I can't see it.
 
P

Paul Morrow

Anthony said:
So what's the point of this, then? You say it's an "anti-decorator" metaclass.
It's not. It's simply a way to automagically invoke a couple of standard
decorators from a metaclass, based on people following a convention.

It does little or nothing to address many of the other requirements for
decorators, is brittle (see my previous post on the subject) and relies on
something that is merely a convention, and deliberately so.

The class was named a little prematurely, but the point was to show that
decorator syntax wasn't needed for static or class method declarations
as simply following a convention does the job just fine. Just as it
does for private and semi-private methods. Are we planning on keeping
that convention? Or will we be phasing that out in favor of a method
visibility decorator?
I fail to see how your hack, which merely removes two of the most trivial
examples of decorator use, addresses anything in the general case.

It doesn't, yet. Again, this is only targeting method types at the moment.
As far as a "better, less objectionable solution" - as I've said time and time
again, this subject has had 2+ years of discussion. Do you honestly
expect that 2 or 3 more weeks here or there is going to produce some
blinding flash of insight? I'd love it to be true, but really, I can't see it.

We're about to do something to the language that will make it less
readable and more intimidating. That's bad. So maybe if we limit the
scope of what decorators need to do, they won't be used that often. And
that would be good.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top