Getting rid of "self."

Alex Martelli aleaxit at yahoo.com
Sun Jan 9 06:31:47 EST 2005


BJörn Lindqvist <bjourne at gmail.com> wrote:

> I think it would be cool if you could refer to instance variables
> without prefixing with "self." I know noone else thinks like me so

Some do -- Kent Beck's excellent book on TDD-by-example has a specific
grouse against that in the chapter where he develops the unittest module
(in Python).  But that's how comes Kent is a _Smalltalk_ programmer
rather than a _Python_ programmer, see?-)

> Python will never be changed, but maybe you can already do it with
> Python today?

Sure.

> impressive in this case but much cooler when there is more instance
> variables around. But the solution is very ugly because you have to
> write exec(magic()) in every method. So I'm asking here if someone
> knows a better way, maybe using decorators or metaclasses or other
> black magic?

A decorator can entirely rewrite the bytecode (and more) of the method
it's munging, so it can do essentially anything that is doable on the
basis of information available at the time the decorator executes.  You
do, however, need to nail down the specs.  What your 'magic' does is
roughly the equivalent of a "from ... import *" (except it "imports", so
to speak, from a namespace that's not a module): it makes a local copy
of all names defined in the given namespace, and that's all.  The names
stay local, any rebinding of a name has no non-local effect whatsoever,
etc.  Is this indeed what you want -- just give a method this kind of
copies?  And still have to write self.x=23 for re-binding (without
effect on the local copy, note...)?  Or what else?

Then, you must decide whether this applies to all names the method
accesses (which aren't already local).  For example, if the method has a
statement such as:
    x = len(y)
and does not otherwise as locals len nor y, does this mean
    x = self.len(self.y)
or
    x = len(self.y)
or
    x = self.len(y)
or
    x = len(y)
...?  I.e., which of the names len and y is meant to be a global or
builtin, which is meant to be an isntance variable?  The decorator must
know, because it needs to generate different bytecode.  Your approach,
injecting an exec statement in the method, makes the compiler punt: the
compiler knows, seeing 'exec', that it has no idea about which names are
locals or globals any more, so it generates horribly-slow code for
completely-general accesses instead of normal local-access-is-optimized
code.  Is that what you want to do -- slow all of your Python code down
by an order of magnitude in order to be able to avoid writing 'self.' in
a few cases?

If you can give totally complete specifications, I can tell you whether
your specs are doable (by a decorator, or other means), how, and at what
cost.  Without knowing your specs, I can't tell; I can _guess_ that the
answer is "probably doable" (as long as you're not demanding the code in
the decorator to be an oracle for the future, but are content to limit
it to information known when it runs; and as long as you don't care how
much you slow everything down) and most definitely not WORTH doing for
anything except mental gym.


Alex



More information about the Python-list mailing list