1

I'm trying to write a replacement for the print() function; I'd like to understand what Python 3 is doing here.

Consider the following two Python 3 source files:

file.py:

def in_a_file(): print("this is in a file") 

minimal.py:

import builtins from file import * def test(): print("this is a test") def printA(*args, **kwargs): builtins.print("A: ", end="") builtins.print(*args, **kwargs) print = printA test() in_a_file() 

When I run minimal.py, I get this output:

A: this is a test this is in a file 

So, clearly, the assignment print=printA has changed the behavior of print() in function test(), but not in function file().

Why?

And, is there code I could put in minimal.py that would similarly change the behavior of print() in function file()?

8
  • 6
    A module has its own namespace, it doesn't use the variables defined in the file that imports it. Commented Jan 20, 2021 at 19:50
  • @Barmar I suppose you're correct, but can you please elaborate? I don't understand how "it doesn't use the variables defined in the file that imports it" explains what I'm seeing. Or how to get the behavior I want - which is to change the way print() in the module works. Commented Jan 20, 2021 at 19:51
  • Does this answer your question? Python3 global scoping in different modules Commented Jan 20, 2021 at 19:53
  • Does this answer your question? Short description of the scoping rules? Commented Jan 20, 2021 at 19:54
  • 2
    Every module has its own namespace where it looks up variable names. So the variable print in your file is not the same as the one in file.py. This is done so that module authors don't have to worry that their variables might conflict with variables in the caller. Commented Jan 20, 2021 at 19:54

1 Answer 1

1

The name lookup is roughly builtins shared by all modules, each module's own global namespace, and then subsequently nested function/class namespaces. The print function lives in builtins, and is thus visible in all modules by default.

The assignment print = printA in minimal.py adds a new name print to minimal's global namespace. This means minimal.print shadows builtins.print inside the minimal module. The change is not visible in any other module, since each has a separate module-global namespace.

To change print across all modules, re-assign builtins.print.

import builtins _real_print = builtins.print def printA(*args, **kwargs): _real_print("A: ", end="") _real_print(*args, **kwargs) builtins.print = printA 
Sign up to request clarification or add additional context in comments.

1 Comment

Another possibility is to do file.print = printA.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.