【问题标题】:How to change a yielded value如何更改屈服值
【发布时间】:2019-06-10 03:30:38
【问题描述】:

以下代码使用上下文管理器将变量存储和加载到文件中。 但是,必须设置上下文管理器 (loaded.value) 生成的内容的 value 属性非常烦人。 我愿意

  1. 不必定义像LoadedValue这样的新类
  2. 将上下文管理器 (loaded) 的生成值设置为保存的值。

我们将不胜感激。

import os
import pickle
from contextlib import contextmanager

class LoadedValue:
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return "<LoadedValue: {}>".format(self.value)

@contextmanager
def load_manager(load_file="file.pkl"):
    with open(load_file, "rb") as f:
        loaded_object = LoadedValue(pickle.load(f))
    try:
        yield loaded_object
    finally:
        with open(load_file, "wb+") as f:
            pickle.dump(loaded_object.value, f)

if __name__ == "__main__":
    filename = "test.pkl"
    with open(filename, "wb+") as f:
        pickle.dump(7, f)

    with load_manager(filename) as loaded:
        print(loaded) # >>> <LoadedValue: 7>
        loaded.value = 5 # this is what I have to do
        # loaded = 5  # this is what I want to do

    with load_manager(filename) as loaded:
        print(loaded) # >>> <LoadedValue: 5>

注意:这是 CodeReview 上的 originally posted,但我决定在此处重新发布以获取答案,并将其留在 CodeReview 以帮助以其他方式改进代码。

【问题讨论】:

  • 不,python中没有赋值重载,所以你必须将它附加到某个东西上......并且那个范围内的东西不能被产生loaded_object的地方访问......所以你必须附加它(你可以重写 += 或者你想要的东西......或者你可以通过定义 LoadedValue 类的 __call__ 方法来做类似加载(5)的事情
  • @JoranBeasley 如果您想将其添加为答案,我现在会接受(除非有人想出办法)

标签: python python-3.x yield contextmanager


【解决方案1】:

没有办法覆盖python中的赋值运算符,所以你不能做loaded = 5

(你可以覆盖其他东西,这样它可能会起作用)

  • 覆盖__call__ 以允许loaded(5)
  • 覆盖__lshift__ 以允许loaded &lt;&lt; 5
  • 覆盖__ior__ 以允许loaded |= 5

(但请注意你的同事,否则未来的同事可能永远不会原谅你)

此外,在with XXXX as Y: 块范围内发生的事情(通常)不能被产生上下文的方法访问,除非该范围以前可以被产生范围的地方访问(即全局命名空间等)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多