Overriding a global

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Dec 12 20:48:43 EST 2011


On Tue, 13 Dec 2011 09:27:09 +1100, Ben Finney wrote:

> Dave Angel <d at davea.name> writes:
> 
>> True, but in this code, the function is trying to both use the global
>> value, but also a local that deliberately has the same name, but a
>> different meaning and "value". The CPython compiler doesn't make this
>> easy, and I think the globals() technique is unnecessarily obscure, as
>> is the default-argument trick.
> 
> I disagree. The language makes it difficult, and it *should* be
> difficult to do what you describe.
> 
> The tricks to achieve it are obscure and ugly, which is a good thing
> IMO: they're a code smell that the design of the code needs changing.

Devil's Advocate: perhaps not. Think of local and global names as 
analogous to instance and class attributes. There are good use cases for 
making something a class attribute, while allowing instances to override 
that name with an instance attribute. I see a reasonable case for saying 
"use this global, unless a local overrides it".

Similarly, globals override built-ins with the same name; while 
monkeypatching needs to be used with care, it is a legitimate technique.

To a human reader, the following pseudocode might be ambiguous, but 
either case makes sense:

x = 1
def spam():
    print x  # prints 1
    x = 2  # does this create a new local x, or modify the old global x?
    print x  # unambiguously prints 2

print x  # prints 1 or 2


Python doesn't allow this, but another language might; in Python, a 
reasonable way to get similar behaviour might be:

x = 1
def spam():
    print globals()['x']
    x = 2  # unambiguously creates a new local x
    print x  # unambiguously prints 2

print x  # unambiguously prints 1


-- 
Steven



More information about the Python-list mailing list