Per-file default print settings

I have an idea for Python that could make repeated print formatting easier.

For example, sometimes users repeatedly write:

print(..., end=" ")
print(..., sep="\n")

I wonder whether Python could support configurable per-file default print settings, such as:


sys.defaults.print.end = " "

or perhaps:

# py: print.end=" "
# py: print.sep="\n"

This could reduce repetition in scripts that frequently use the same print formatting.

I understand that explicit behavior is important in Python, but I wanted to share the idea and hear opinions from the community.

You can just define your own function, either with its own name (usually preferred) or a file that just locally shadows the print function from the __builtins__ module:

def print(*args, sep='\n', end=' ', file=None, flush=False):
    __builtins__.print(*args, sep=sep, end=end, file=file, flush=flush)

That`s it.

8 Likes

I think this pretty much sums up my thoughts on the matter. A longer print statement, to me, is probably well worth the clarity in (almost?) every instance.

Note that this wouldn’t apply only to your file: it would change the behavior of the interpreter for the entire program, including any libraries you are calling that use print. This is a big blunt hammer that will do more than you intended.

4 Likes

Yes, I think it more common to mix explicit print keyword args in a file than to use one for every print in a file. The latter to me seems too rare to justify new syntax rather than a custom function.

Correct. Sometimes I write my own print wrapper when I would need end="" more often, like when I want to print many strings that already end with newline. In such cases, I would then use the wrapper consistently and add explicit newlines where I need it.

In such a case, I would call the wrapper ‘pnn’ for ‘print no newline’ so it would be both obvioulsly distinct from ‘print’ and save keystrokes.

Just put this (almost) one-liner at the beginning of your file:

from functools import partial
print = partial(print, end="")

functools.partial allows you to pre-define defaults for a function. Then you can shadow the original function with its partial.

5 Likes

According to the CPython documentation, it is warned against using __builtins__ and the imported module builtins should be used instead.

As an implementation detail, most modules have the name __builtins__ made available as part of their globals. The value of __builtins__ is normally either this module or the value of this module’s __dict__ attribute. Since this is an implementation detail, it may not be used by alternate implementations of Python.

1 Like

You can define default kwargs as a dictionary in a module:

# defaults.py

default = {'end': ' '}

# main.py

from defaults import default

print(..., **default)

I believe that pydantic used to do this before dataclass(slots=True) was fully supported and they used @dataclass(**has_slots) where has_slots was determined based on the current version you were running, or a feature test in a private module.

You can also dynamically modify that default dictionary at runtime. Or have it stored as a class attribute so users can modify it based on the context they’re using the object in.

I’d like to ask people thinking that per-file settings of a function (print or other) would be a great idea to check if they are not actually looking for something little bit different. When I wanted to have per-file settings of some function, I realized that actualy I want them to be applied not only to code in that file, but also to code called from withing the file. So it was not really per-file settings, but rather something like per-file default context. Obviously that makes everything much more complicated.

1 Like