【问题标题】:Is there a pythonic way to wrap a class using with statement?有没有一种 Python 的方式来使用 with 语句来包装一个类?
【发布时间】:2021-05-05 08:05:44
【问题描述】:

我做了以下,它有效,但我怀疑它的稳健性。

import B

class A():
    def __init__(self):
        self._b = B()

    def __enter__(self):
        return self._b .__enter__()

    def __exit__(self, exc_type, exc_val, exc_tb):
        return self._b .__exit__(exc_type, exc_val, exc_tb)

我知道 B.__enter__()B.__exit__() 方法不应该在 B 之外使用,但我没有找到其他方法来做到这一点。 以这种方式包装一个类是否可以接受? 还有其他方法吗?

我知道答案可能是:“不,这正是 with 旨在防止的”

【问题讨论】:

  • 单独来看,如果 A 是 B 的子类,这将是优雅而明显的。
  • 这个包装类的用例是什么?为什么需要它?
  • 这对于实现上下文管理器来说是非常好的。不过,根据您想要做的事情,contextlib.contextmanager 可能会为您做这件事。
  • @azro,不,我没有看到关于在那里包装的信息
  • blhsing,我需要根据 A 类上的参数不同地实例化 B 类 @tripleee,由于上述原因,我首先忽略了这个选项,但我们实际上可以调用 supper().__init__ () 具有不同的参数,具体取决于我所做的 A 收到的内容并且它有效,我会就此写一个答案,谢谢

标签: python wrapper with-statement


【解决方案1】:

“方法B.__enter__()B.__exit__()不应该在B之外使用”这句话是为了教新手程序员如何正确使用with语句。

但是,您正在实施它。你正在做的事情是完全可以接受和正确的。其实我也不知道有什么更好的办法。

【讨论】:

    【解决方案2】:

    这个问题实际上可以通过使用子类而不是包装器来解决(感谢@tripleee) 我忽略了这个选项,因为父类必须根据子类参数进行不同的实例化。但这可以按如下方式完成:

    import B
    
    class A(B):
        def __init__(self, parameter):
            if parameter == 1:
                super().__init__(x=1)
            elif parameter == 2:
                super().__init__(y=2, z=3)
            else:
                raise ValueError
    

    【讨论】:

    • 请记住,如果“子类”只添加像这样的__init__,您可以只使用一个函数。
    • @MisterMiyagi 确实如此。这是一个简化版本,实际上有很多 x、y、z 参数我想从 A 外部隐藏,而 A 需要适合我无法修改的使用类的框架
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 2011-09-18
    • 1970-01-01
    • 2015-08-27
    相关资源
    最近更新 更多