[Python-Dev] new draft of PEP 227

Tim Peters tim.one@home.com
Sun, 17 Dec 2000 03:30:24 -0500


[Tim]
>> I've rarely seen problems due to shadowing a global, but have often
>> seen problems due to shadowing a builtin.

[Paul Prescod]
> Really?

Yes.

> I think that there are two different issues here. One is consciously
> choosing to create a new variable but not understanding that there
> already exists a variable by that name. (i.e. str, list).

Yes, and that's what I've often seen, typically long after the original code
is written:  someone sticks in some debugging output, or makes a small
change to the implementation, and introduces e.g.

    str = some_preexisting_var + ":"
    yadda(str)

"Suddenly" the program misbehaves in baffling ways.  They're "baffling"
because the errors do not occur on the lines where the changes were made,
and are almost never related to the programmer's intent when making the
changes.

> Another is trying to assign to a global but actually shadowing it.

I've rarely seen that.

> There is no way that anyone coming from another language is going
> to consider this transcript reasonable:

True, but I don't really care:  everyone gets burned once, the better ones
eventually learn to use classes instead of mutating globals, and even the
dull get over it.  It is not, in my experience, an on-going problem for
anyone.  But I still get burned regularly by shadowing builtins.  The burns
are not fatal, however, and I can't think of an ointment less painful than
the blisters.

> >>> a=5
> >>> def show():
> ...    print a
> ...
> >>> def set(val):
> ...     a=val
> ...
> >>> a
> 5
> >>> show()
> 5
> >>> set(10)
> >>> show()
> 5
>
> It doesn't seem to make any sense. My solution is to make the assignment
> in "set" illegal unless you add a declaration that says: "No, really. I
> mean it. Override that sucker." As the PEP points out, overriding is
> seldom a good idea so the requirement to declare would be rarely
> invoked.

I expect it would do less harm to introduce a compile-time warning for
locals that are never referenced (such as the "a" in "set").

> ...
> The "right answer" in terms of namespace theory is to consistently refer
> to builtins with a prefix (whether "__builtins__" or "$") but that's
> pretty unpalatable from an aesthetic point of view.

Right, that's one of the ointments I won't apply to my own code, so wouldn't
think of asking others to either.

WRT mutable globals, people who feel they have to use them would be well
served to adopt a naming convention.  For example, begin each name with "g"
and capitalize the second letter.  This can make global-rich code much
easier to follow (I've done-- and very happily --similar things in
Javascript and C++).