A better self (again)

Michele Simionato mis6 at pitt.edu
Wed Jul 24 17:36:40 EDT 2002


That thread started as a request to have a better self implemented in the
language. Since the usage of self seems so eradicated that probably will never 
be modified (which can be a good or a bad thing depending on your personal 
taste) I suggest a simple recipe to avoid typing self and having a 
preprocessor inserting automatically self in the right positions. IMHO this 
recipe is better than having a metaclass doing the job (as suggested by
Alex Martelli) because:

1. It is simpler.
2. It is fast: on an old Pentium II 366MHz it takes only one second to process 
100.000 lines of code !
2. In the metaclass approach the pseudocode has to be entered as a python 
docstring: this means that it will not be correctly highlighted by the editor, 
which is a nuisance.
3. It is quite simple to configure Emacs in such a way to invoke automatically 
the preprocessor (I guess in idle too), therefore one can write and check the 
pseudocode directly. Notice that if an error occurs, Emacs automagically goes
to the correct line in the pseudocode !
4. When the program works, one can save it as standard code and reuse it as 
a module or distribute it. People will not get fool in trying to understand
your metaclass hacking.

Of course a simpler alternative is to learn to appreciate self :-) 

Personally, self does not bother me very much. I have chosen the example of self
as an appliication of the general idea of a Python preprocessor. It could be handy 
for saving typings in various situations. One could even define abbreviations for '
reserved words and tokens of the language, even if I would not recommend that.

For people working in Unix-like OS and using Emacs, this is the recipe,
simple as the ABC:

A. Save the preprocessor code in an executable file called pp:

---begin pp---

#!/usr/bin/python
from os import popen
import sys

def process(pseudocode): 
    from re import compile
    comma=compile(r'\(\s*,')
    dot=compile(r'[^\w_\)\]]\.[a-zA-Z_]+')
    code=comma.sub('(self,',pseudocode)
    end=0; newcode=''
    for found in dot.finditer(code):
        start=found.start()
        newcode+=code[end:start+1]+'self'
        end=found.end()
        newcode+=code[start+1:end]
    return newcode+code[end:]

nargs=len(sys.argv)-1
if nargs==0: #execute the pseudoprogram
    out=process(sys.stdin.read())
    popen('python2','w').write(out)
elif nargs==1: #print to file
    print >>file(sys.argv[1],'w'),process(sys.stdin.read())
else:
    print """Too many arguments. 
Usage: pp < pseudo.py 
       pp normal.py < pseudo.py"""

---end pp---

this preprocessor convert 

"(," --> "(self," 

and 

".something" --> "self.something" 

B. Write your pseudopython program, for instance this one, which avoids self:

---begin pseudo.py---

from math import sin,sqrt
import sys

class Example:
    y,z,t=1.0,1.0,1.0
    def f(,x):
       return sin(.t)*x**.y+sqrt(.z)

example=Example()
print example.f(1.0)

---end pseudo.py

The preprocessor reads from the standard input and the pseudopython program
can be executed as follows:

$ pp < pseudo.py 

It can be converted to normal code as follows:

$ pp normal.py < pseudo.py

One can also write code on the fly, for instance

$ pp
print 1+1
CTRL-D
2

C. If you want to write and execute pseudopython programs from Emacs,
add the line

(setq py-python-command "pp")

in the .emacs file. Emacs will highlight the pseudocode and in case of errors 
will jump to the correct line !

Maybe somebody want to try it. Obviously the preprocessor can be extended
and improved to recognize any kind of new sintax you like. You can design
your personal Python without bothering the official designers ! :-)

---
Michele Simionato - Dept. of Physics and Astronomy
210 Allen Hall Pittsburgh PA 15260 U.S.A.
Phone: 001-412-624-9041 Fax: 001-412-624-9163
Home-page: http://www.phyast.pitt.edu/~micheles/



More information about the Python-list mailing list