[Python-ideas] Mitigating 'self.' Method Pollution
steve at pearwood.info
Sat Jul 11 17:07:56 CEST 2015
On Sat, Jul 11, 2015 at 06:38:34PM +1000, Chris Angelico wrote:
> On Sat, Jul 11, 2015 at 6:33 PM, Ben Finney <ben+python at benfinney.id.au> wrote:
> >> And, for folks who still prefer to prefix all their field references
> >> with 'self.', the proposal in no way prevents them from doing so. It
> >> merely allows the rest of us to be a bit less wordy and more pithy in
> >> our code.
> > Python requires explicit declaration of the namespace for names. That
> > protects me from ambiguities that would otherwise be very common in
> > other people's code. I appreciate that and do not want it threatened.
> Not quite true; Python requires explicit declaration of names when
> they're bound to,
No it doesn't. It only requires an explicit declaration of names when
you don't wish to use the default *implicit* rule that any name you bind
to is a local.
Accessing a local is always implicit. You cannot declare locals at all
(apart from function parameters). You just bind to a name, and Python
implicitly treats them as local.
Accessing nonlocals and globals may be implicit or explicit, depending
on whether you use a global or nonlocal declaration.
Accessing builtins is implicit, unless you import builtins and write
"builtins.len" (say), which we hardly ever do.
In Python, most variables (or name bindings, if you prefer) are
implicitly scoped. It is rare that they are explicitly scoped as global,
and when they are, that's usually a code smell. ("Global variables
considered harmful.") The same applies to attribute access: we normally
don't explicitly read from a particular scope. That goes against the
principle of inheritence. When you look up "self.attr", you don't know
whether the attribute returned will come from the instance __dict__, the
class, or a superclass, the scope is implied by the history and type of
the instance itself.
To say nothing of descriptors like property, or methods. That's about as
implicit as you can get.
A naive reading of the Zen would suggest that, explicit being better
than implicit (what, always? under all circumstances?), Python must be a
pretty crap language, it has got so many implicit semantics...
In contrast, the new rule suggested is *explicit*. You explicitly
declare that a name belongs to the scope:
self spam, eggs, cheese
declares that spam, eggs and cheese are members of self. That's good
enough for nonlocals and globals.
(By the way, I used to prefix all my global variables with "g", to be
explicit that they were global. That stage in my development as a
programmer didn't last very long. Fortunately, I was never silly enough
to prefix all my locals with "l".)
Ben has agreed that it would be harmful to have to explicitly scope each
and every name access:
if not builtins.len(nonlocals.x + locals.y):
I trust that everyone agrees with this point. So it seems that explicit
is *not* always better than implicit. So why do we behave as if the Zen
of Python is some source of ultimate truth? The Zen is not supposed to
be a thought-terminating cliche. As Terry Reedy wrote a few years ago:
"People sometimes misuse Tim Peter's Zen of Python points. He wrote
them to stimulate thought, not serve as a substitute for thought, and
certainly not be a pile of mudballs to be used to chase people away."
When you read a line of code in isolation:
spam = eggs + cheese
there is no hint, no clue, as to which of these are globals, nonlocals,
locals, or even builtins. And yet we cope with the ambiguity, and I
don't hear people claiming that we need to explicitly tag names with
their scope, as we do with attributes.
So what makes attributes so special that we have to break the rules that
apply to all other variables?
No tags needed: builtins, globals, nonlocals, locals.
Tags needed: attributes.
This isn't a rhetorical question, but this post is long enough, and I
daresay half my readers have tuned out a few paragraphs ago, so I'll
take my answer to the question to a new post.
More information about the Python-ideas