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:
- 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.
- 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.