gpt4 book ai didi

python - 使用没有 "with" block 的上下文管理器

转载 作者:太空狗 更新时间:2023-10-30 00:42:42 25 4
gpt4 key购买 nike

下面是我的 my_create 方法的示例,以及该方法的使用示例。

@contextmanager
def my_create(**attributes):
obj = MyObject(**attributes)
yield obj
obj.save()

with my_create(a=10) as new_obj:
new_obj.b = 7

new_obj.a # => 10
new_obj.b # => 7
new_obj.is_saved() # => True

对于 Ruby/Rails 的用户来说,这可能看起来很熟悉。它类似于 ActiveRecord::create 方法,with block 中的代码充当一个 block 。

但是:

with my_create(a=10) as new_obj:
pass

new_obj.a # => 10
new_obj.is_saved() # => True

在上面的示例中,我向我的 my_create 函数传递了一个空“ block ”。一切按预期工作(my_obj 已初始化并保存),但格式看起来有点不稳定,而且 with block 似乎没有必要。

我希望能够直接调用 my_create,而不必设置 passing with block 。不幸的是,这对于我当前的 my_create 实现是不可能的。

my_obj = create(a=10)
my_obj # => <contextlib.GeneratorContextManager at 0x107c21050>

我必须在 GeneratorContextManager 上同时调用 __enter____exit__ 以获得我想要的结果。

问题:

有没有办法编写我的 my_create 函数,以便可以使用“ block ”作为可选“参数”来调用它?我不想将可选函数传递给 my_create。我希望 my_create 能够可选地让出代码块的执行。

解决方案不必涉及withcontextmanager。例如,使用 generatorfor 循环可以获得与上述相同的结果,尽管语法变得更加不清楚。

在这一点上,恐怕还不存在可读性强且易于使用的解决方案,但我仍然很想看看每个人都想出了什么。

一些说明:

另一个例子是:

@contextmanager
def header_file(path):
touch(path)
f = open(path, 'w')
f.write('This is the header')
yield f
f.close()

with header_file('some/path') as f:
f.write('some more stuff')

another_f = header_file('some/other/path')

我一直想执行上下文管理器的 __enter____exit__ 部分。我并不总是想提供一个 block 。如果不需要,我不想设置 passing with block 。

这在 Ruby 中是可能且容易的。如果在 Python 中也可行,那就太好了,因为我们已经很接近了(我们只需要设置一个 passing with block )。我知道语言机制使它变得困难(技术上不可能?),但我对足够接近的解决方案很感兴趣。

最佳答案

MyObject 上添加一个创建 保存的新方法。

class MyObject:

@classmethod
def create(cls, **attributes):
obj = cls(**attributes)
obj.save()
return obj

这是一个备用初始化程序,一个 factory ,设计模式在 Python 标准库和许多流行的框架中都有先例。 Django models use this pattern其中备用初始化程序 Model.create(**args) 可以提供通常的 Model(**args) 不会提供的额外功能(例如持久化到数据库)。

Is there a way to write my my_create function so that it can be called with a "block" as an optional "parameter"?

没有。

关于python - 使用没有 "with" block 的上下文管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48591771/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com