Shadowing, was Re: learning python ...

Peter Otten __peter__ at web.de
Tue May 25 05:46:31 EDT 2021


On 25/05/2021 05:20, hw wrote:

>> We're talking about many different things. If it's simply "num = ..."
>> followed by "num = ...", then it's not a new variable or anything,
>> it's simply rebinding the same name. But when you do "int = ...", it's
>> shadowing the builtin name.
> 
> Why?  And how is that "shadowing"?
> 
> What if I wanted to re-define the built-in thing?


When you write

foo

in a module the name "foo" is looked up in the module's global 
namespace. If it's not found it is looked up in builtins. If that lookup 
fails a NameError exception is raised.

 >>> import builtins
 >>> builtins.foo = "built-in foo"
 >>> foo
'built-in foo'
 >>> foo = "module-global-foo"  # at this point builtins.foo is shadowed
 >>> foo
'module-global-foo'
 >>> del foo # delete the global to make the built-in visible again:
 >>> foo
'built-in foo'

That mechanism allows newbies who don't know the builtins to write

list = [1, 2, 3]

without affecting other modules they may use. It also allows old scripts 
that were written when a builtin name did not yet exist to run without 
error.

The problem you ran into, using a name in two roles

float = float("1.2")

could be circumvented by writing

float = builtins.float("1.2")

but most of the time it is more convenient to think of builtins as names 
that are predefined in your current module and act accordingly.

As you see redefining a builtin is as easy as importing builtins and 
setting the respective attribute

 >>> builtins.float = int
 >>> float(1.23)
1



More information about the Python-list mailing list