【问题标题】:should the return value for `__enter__` method always be `self` in python`__enter__` 方法的返回值是否应该在 python 中始终为 `self`
【发布时间】:2016-11-11 22:04:18
【问题描述】:

__enter__ 方法的返回值不应该总是self

Python documentation 说:

object.__enter__(self) 输入与此相关的运行时上下文 目的。 with 语句将此方法的返回值绑定到 语句的 as 子句中指定的目标(如果有)。

有了这个,为了做任何实际的事情,不应该总是从类的__enter__ 方法返回self,因为没有它,我们将无法在上下文中调用其他类方法。

例如,在以下代码中,s.main() 工作正常,但 b1.main() 出错。

class a(object):
    def __init__(self):
        pass

    def __enter__(self):
        return self

    def __exit__(self ,type, value, traceback):
        return self

    def main(self):
        print " in a::main self %d " , id(self)


class b(object):
    def __init__(self):
        pass

    def __enter__(self):
        return "something else"

    def __exit__(self ,type, value, traceback):
        pass

    def main(self):
        print "in b::main !! self id " , id(self)

with a() as s:
    s.main()

with b() as b1:
    b1.main()

s = a()
s.main()

【问题讨论】:

  • 问题归结为“你能想象一个案例,从__enter__ 返回除self 以外的其他内容是可行的”。而且,嗯,这取决于你的幻想。
  • 我认为任何对此问题感兴趣的人也可能会从 MisterMiyagi 对my related question的更详细回答中受益

标签: python


【解决方案1】:

如果使用实例的属性作为上下文管理器有意义,则不是:

class A:
    def __init__(self, useful_obj):
        self.useful_obj = useful_obj

   def __enter__(self):
       return self.useful_obj

   def __exit__(self):
       pass

with A(some_obj) as a:
    # magic done implicitly by a.useful_obj
    .
    .
    .

这种情况可以在SqlAlchemy的code看到。

如果您使用任何str 方法,您提供的代码示例将起作用,例如:

with b() as b1:
    print b1.upper()

>> SOMETHING ELSE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2021-10-11
    • 2016-12-17
    • 2010-09-24
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多