PEP 318 : Def and Class in expressions

John Roth newsgroups at jhrothjr.com
Sat Mar 27 21:56:18 CET 2004


"PF" <peufeu at free.fr> wrote in message news:opr5jagci1b723ru at news.free.fr...
>
> Hello,
>
> I'm pleased to see activity on this topic as it pains me to write
> "classmethod" two pages of code after the method definition. However I
> find the decorators to obfuscate the syntax and lessen the expressivity
> (ie. they restrain what can be done).

Why are you writing methods that long? (That's rhetorical -
I'd break it up so I could understand it)

>
> All these problems come from the fact that the execution of the
> "foo=staticmethod(foo)" must be delayed after the execution of the "def"
> statement because it must act on the function after it has been defined.

That isn't the only problem, but it's the one most often cited.

> Normal program execution thus flow forces it to be placed after the
> "def", while readability would require it to be placed *before* the 'def'.

I'd prefer it as part of the same expression as the 'def'. That makes it
quite clear, and eliminates any possible confusion from having two
assignments where one should be sufficient.

> How to reverse the execution order ? One method would be to use an
> expression, but that would get very ugly soon, and Python's indented
> syntax does not lend itself well to such twistings. To mix a few previous
> postings :
>
> mymethod = staticmethod(def(args):
>     method code...
>     )
>
> is just plain ugly.

Agreed. I don't like the trailing parenthesis on another line.
Avoiding that is part of the joy of Python. (Notice that
I've reworked your example to conform to Guido's style
rules.)

> mymethod = staticmethod(def(args)):
>     method code...

> is also quite ugly.

Why? Except for the ':', which I would eliminate (although
there are arguements for keeping it) I think it reads quite well.

>
> I don't like the decorators either.

Neither do I. I don't find that any version of the syntax flows.

> So the root of the problem is the fact that the source code executes from
> top to bottom. I see two solutions.
> 1. Use a text editor which can fold functions, hiding the code between
> the def and the staticmethod call

That doesn't fix it; there's still two statements where there should
be only one.

> 2. Reverse the flow of code.

I'm going to stop here and go off in another direction...
[snip rest of post]

As I said above, I find:

aMethod = staticmethod(def(parms))
    statements

to be quite readable. The indentation says everything I need
said to understand it while scanning without having to resort
to studying the syntax (which I would have to do with brace-
bound languages.)

Multiple decorators fall out without any effort. There are
really only two issues:

1. The lack of a ":" at the end.

2. How to handle multiple blocks in one expression.

On item 1. There are two good reasons for the ":":
readability and the fact that most Python aware editors
use it for automatic indentation.

Regardless of what happens, readability is going to take
a hit, and the editors can be patched.

The way to handle item 2 is with the following set of
indentation rules:

1. There may be at most one 'def' on a line (*not* in a
statement!)

2. If the expression containing the def does not end naturally
on the same line as the ')' at the end of the def, parsing of
the expression is  suspended at the end of that line (*not*
immediately after  the ')'. The reason for this rule is to allow
the containing statement to end in the most readable fashion,
if possible.

3. The statements for the def follow immediately
on the next line and following lines, indented either 1 or 2
levels depending on whether the containing expression ended
or was suspended.

4. The body of the function/method ends, as usual, when
any line is indented less (that is, farther to the left) than the
body of the function/method.

5. A suspended expression continues on the line immediately
after the end of the function body. It must be indented to the
left of the function body, and to the right of the indentation for
the statement containing the expression.

In looking at this, I see one other problem: a multi-line
statement that contains several lines after the last one that
contains a 'def'. My personal preference is that I can finish
out the statement before writing the function body, but I
don't see a way of managing both multiple blocks in one
expression and doing this.

Finally, I have another reason for liking this particular
syntax. It lets me stick methods into instances quite
directly, without having to invent yet another syntax, or
leaving them bound at the module level to both be bound
into the instance and also cleaned up from the module.
That's something that I need for certain kinds of programs
that are more easily expressed with a proto-type based
language, such as interactive fiction.

John Roth

>
> Pierre





More information about the Python-list mailing list