Я пытаюсь создать класс, который подавляет stdout и stderr. У меня он не работает при использовании with statement
, но я хочу расширить функциональность, чтобы также использовать его в качестве декоратора, который я можно использовать для подавления вывода функций. Возможно ли, чтобы все полностью содержалось в классе, или оболочка должна быть функцией вне класса?
Я пытаюсь следовать этим ресурсам, но мне сложно адаптироваться к моей ситуации:
https://stackabuse.com/pythons-classmethod-and-staticmethod-explained/
Как реализовать Python декоратор с аргументами как класс?
import os,sys, functools
class Suppress(object):
def __init__(self, show_stdout=False, show_stderr=False):
self.show_stdout = show_stdout
self.show_stderr = show_stderr
self.original_stdout = None
self.original_stderr = None
def __enter__(self):
devnull = open(os.devnull, "w")
# Suppress streams
if not self.show_stdout:
self.original_stdout = sys.stdout
sys.stdout = devnull
if not self.show_stderr:
self.original_stderr = sys.stderr
sys.stderr = devnull
def __exit__(self, *args, **kwargs):
# Restore streams
if not self.show_stdout:
sys.stdout = self.original_stdout
if not self.show_stderr:
sys.stderr = self.original_stderr
def __call__(self, *args, **kwargs):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
with self(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
return decorator
with Suppress(show_stdout=False, show_stderr=False):
print("stdout", file=sys.stdout)
print("stderr", file=sys.stderr)
Я также пытаюсь использовать эту функцию в качестве декоратора:
@Suppress(show_stdout=True)
def f(x, y):
print(x, file=sys.stdout)
print(y, file=sys.stderr)
return x*y
a = f(1,2)
# 1
# a = 2
У меня было аналогичный декоратор работает (хотя и очень некрасиво) для оболочки в стиле matplotlib
. Однако это должно было использовать внешнюю функцию и не входило в класс.
# # Decorators
# def stylize(style="seaborn-white"):
# def decorator(func):
# @functools.wraps(func)
# def wrapper(*args, **kwargs):
# with plt.style.context(style):
# return func(*args, **kwargs)
# return wrapper
# return decorator
# # Wrappers
# def subplots_wrapper(style="seaborn-white", *args, **kwargs):
# @stylize(style)
# def inner_wrapper(*args, **kwargs):
# return plt.subplots(*args, **kwargs)
# return inner_wrapper(*args, **kwargs)