python - 如何在 "decorator"对象中实现 "class"功能?

标签 python class object stdout decorator

我正在尝试构建一个抑制 stdout 和 stderr 的类。 当用作 with statement 时,我把它放下了但我想扩展功能以用作装饰器,我可以用它来抑制函数的输出。是否可以将所有内容完全包含在类中,或者包装器是否需要成为类之外的函数?

我正在尝试遵循这些资源,但很难适应我的情况:

https://stackabuse.com/pythons-classmethod-and-staticmethod-explained/

How to implement Python decorator with arguments as a class?

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)

最佳答案

如果您只使用 with self,它会起作用没有参数:

   def __call__(self, function):

        @functools.wraps(function)
        def decorated(*args, **kwargs):
            with self:
                return function(*args, **kwargs)
        return decorated

关于python - 如何在 "decorator"对象中实现 "class"功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61685971/

相关文章:

python - 使用 numpy 执行外加法

python - 如何使用 Tkinter 包几何管理器重叠小部件?

c++ - 如何修改一个类,使其只有一个成员函数,所有参数都默认?

java - Multimap Java 的 Multimap - 时间表分类

javascript - Scrapy tbody 标签返回一个空答案但里面有文本

python - 使用按钮从 Tkinter 条目搜索框中获取文本

Python 类变量更改未保存

C++ : Swapping template class elements of different types?

javascript - 将 object.keys 复制到新对象

.net - 一个类中有多少对象太多了?