citynorman
citynorman

Reputation: 5294

How do I redirect output of multiple functions to string or stdout in python? (The reverse of stdout to a variable)

Often I have to print all sorts of diagnostics and I am tired of wrapping everything into a print. Is there something that allows me to just redirect output ie return values of multiple function calls to a string or stdout?

import numpy as np
import pandas as pd

df = pd.DataFrame({'a':range(10)})

# tedious
print(df.describe())
print(df.head())

# better
with something():
    df.describe()
    df.head()

I am aware of Redirect stdout to a file in Python? that is not what I want to do.

Upvotes: 1

Views: 100

Answers (2)

Green Cloak Guy
Green Cloak Guy

Reputation: 24681

Short answer: no.

Long answer: you can maybe do something like this:

def print_all(*expressions):
    for expr in expressions:
        print(expr)

print_all(
    df.describe(),
    df.head(),
)

which comes with a couple caveats:

  1. You couldn't use conventional assignment. When assignment would be required, you'd have to use the assignment operator :=, which is only available in python 3.8, so this would be structured differently than a normal function.
  2. Everything would be evaluated first, before being printed. You could work up some dynamic thing probably by using eval(), but that has other risks.

Alternatively, you could try modifying the df object beforehand so that all relevant methods print their return values - essentially, applying a decorator to every method you want:

def print_wrapper(func):
    def wrap(*args, **kwargs):
        retval = func(*args, **kwargs)
        print(retval)
        return retval
    return wrap

def wrap_funcs(obj, funcnames):
    for funcname in funcnames:
        func = getattr(obj, funcname)
        setattr(obj, funcname, print_wrapper(func))

df = pd.DataFrame({'a':range(10)})
wrap_funcs(df, ['describe', 'head'])

df.describe()
df.head()

This also has caveats, as you'd need to ensure that the names you give it actually are functions or things start going wrong fast, but it should be a possible starting point.

Upvotes: 2

Aasmund Eldhuset
Aasmund Eldhuset

Reputation: 37940

I assume that you want to print the return values of those functions (functions don't "have output" unless they themselves use print or write to a file, in which case your problem would already be solved). You could do this:

def print_many(*values):
    for value in values:
        print value

print_many(
    df.describe(),
    df.head(),
)

Note that this will execute all the functions before anything is printed.

Upvotes: 2

Related Questions