On 12/10/2010 20:14, Seebs wrote:
So, I'm new to Python, though I've got a bit of experience in a few other
languages. My overall impressions are pretty mixed, but overall positive;
it's a reasonably expressive language which has a good mix between staying
out of my way and taking care of stuff I don't want to waste attention on.
My first project was to replace a shell script with a Python script. The
context is a project ("pseudo") which does some really hairy stuff in C.
Part of what it does involves creating hundreds of stub functions. The
existing shell script did this successfully, but wasn't particularly
fast, and was basically unmaintainable. So I've redone it in Python.
The input is a list of C function declarations, such as:
int foo(char *s);
and the output is several files, which include lists of these functions,
declarations for wrappers for them, and so on. So that would produce
something to the effect of:
int foo(char *s) {
/* various magic */
int rc = -1;
/* stuff happens */
rc = wrap_foo(s);
/* more magic */
return rc;
}
Where it gets complicated is that there are, of course, special cases;
for instance, the wrapper for 'int open(char *path, int mode, int flags)' has
to know that the flags argument is conditional, and not always provided, so
it declares open as "int open(char *path, int mode, ...)", then extracts
flags using a va_list. Weird stuff ensues. It's a pretty weird hunk of
code.
The source in its current form:
http://github.com/wrpseudo/pseudo/blob/master/makewrappers
The underlying task is fairly ugly, and it's my first Python project,
so the result isn't particularly pretty, but I'd be interested in
feedback on it. However, I'm not at all sure whether it's appropriate for
this group to post 467 lines of code with no question beyond "how am
I screwing this up?"
At this point, it does everything I want it to do, so the question isn't
"how can I do this?", but "how should I have done this more idiomatically?"
There's a few quirks; one is that I have to run on whatever Python happens
to be installed on a variety of systems, from RHEL4 to Fedora 13 or so.
(It is, at least for now, completely unimportant whether I run on non-Linux
systems.) I can't rely on packages or extensions which aren't going to
be in the base Python install.
Apart from that... I'm interested in feedback. I'm not expecting that
this is good or idiomatic Python, but I'd like to learn to write Python
correctly and expressively, and there's nothing like criticism to improve
code. And if people would prefer that I post the code here, I could,
I just figured that it was a bit large.
The code does require Python 2 and the use of except ... as ... requires
at least version 2.6.
Line 51
The __init__ method should always return None. There's no need to be
explicit about it, just use a plain "return".
Line 68
Instead of:
if not section in self.sections:
use:
if section not in self.sections:
Line 78
This:
file(self.path, 'w')
will never return None. If it can't open the file then it'll raise an
exception.
The error message says:
"Couldn't open %s to read a template."
but it's opening the file for writing.
Line 82
You can't really rely on the destructor __del__ being called.
Line 333
Shouldn't you be checking that the name of the attribute you're setting
doesn't clash with one of the existing attributes? Are you sure that a
dict wouldn't be a better idea?
Line 447
The form:
except ... as ...
is in Python versions >= 2.6, but not earlier.
Line 464
This use of del just deletes the name from the namespace and won't
necessarily call the __del__ method of the 'source' object. It's better
to rely on something more explicit like a 'close' method. (If you can't
be sure which version of Python it'll use then context managers are
probably out anyway!)
--
http://mail.python.org/mailman/listinfo/python-list