- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我真的很喜欢“with open('in_file'') as f”这个语法。我想将该语法用于必须打开和关闭的我自己的资源。
但是,我不明白如何更改我的 open() 方法以启用“with”语法。我可以(并且确实)使用 contextlib.closing() 方法,但重复使用后它变得有点笨重。
因此,我将在下面提出与 shelve.open() 有关的问题。我不建议更改 shelve 模块,而是使用它,因为源代码对所有人来说都是现成的。
与其他需要关闭的标准库资源相比,shelve.open() 没有什么特别之处:socket.socket()、sqlite3.connect()、urllib2.urlopen() 等。
import contextlib, inspect, shelve, sys
#print(inspect.getsource(open)) # can not see how it was done here :-(
print('-' * 40)
# Given that we can view the source for the shelve module:
print(inspect.getsource(shelve))
print('-' * 40)
# Given that we can view the docs for the shelve module:
print(shelve.__doc__)
#print('-' * 40)
# Given that the desired syntax is Pythonic but is not supported:
#with shelve.open('test_shelve') as my_shelve:
# my_shelve['fact_number_1'] = "There's a dead fish on the landing."
# Given that the required syntax is convoluted and
# takes programmer attention away from the task at hand:
with contextlib.closing(shelve.open('test_shelve')) as my_shelve:
my_shelve['fact_number_2'] = "There's another dead fish on the landing."
# Q: What changes would need to made to shelve.open() to allow the
# 'with shelve.open(x) as y' syntax?
我对具有不同名称的额外包装器并不感兴趣。使用 contextlib.closing() 比这更容易、更安全、更直观。我真正感兴趣的是创建一个单独的 open() 方法,可以使用或不使用“with”来调用它。
因此,要成功回答这个问题,您需要获取 shelve 模块的源代码并显示需要对 shelve.open() 进行哪些更改才能拥有一个可以使用或不使用的单一方法'with'(如内置的 open() 或 Python3 urllib.urlopen())。
最佳答案
这里最大的问题是如果你这样做
shelf = the_function_you_want()
你想要的功能必须返回上架,但是如果你这样做
with the_function_you_want() as shelf:
您想要的函数必须返回上下文管理器。这意味着您需要返回一个也是上下文管理器的架子,这反过来意味着您需要创建一个架子子类或猴子补丁 Shelf
。做一个子类可能更好:
class ContextManagerShelf(shelve.DbfilenameShelf):
def __enter__(self):
return self
def __exit__(self, *exc_info):
self.close()
那么你可以使用 ContextManagerShelf
作为上下文管理器,也可以不使用。签名与 shelve.open
相同。如果需要,您还可以制作一个 open
函数来配合它。
关于python - 在不使用 contextlib.closing() 的情况下支持 "with open"语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22397360/
自从我知道了这个模式,我就一直在使用 with open('myfile.txt','w') as myfile: with contextlib.redirect_stdout(myfile
我在 Ubuntu 上使用 Python3.5。以下脚本创建一个文件 out 并用越来越多的“Hello”行填充它: import contextlib with contextlib.redirec
我正在尝试创建一个包装器来使上下文对象成为可选的。当条件为真时,事物应该表现得像包装的上下文对象,否则它应该表现得像无操作上下文对象。此示例适用于使用一次包装对象,但失败了,它被重新使用。 例子: i
我明白了why contextlib.nested is deprecated . 但是如果我为旧的 python 版本编写程序而没有 with 的多种形式(即 < 2.7),我(几乎)别无选择。 为
有谁知道我在哪里可以找到这个 python 模块“contextlib”? root@overo:~# python
我们的代码根据运行时参数调用可变数量的上下文管理器: from contextlib import nested, contextmanager @contextmanager def my_cont
为什么我可以跳过在 yield log_func 中调用 log_func,即我可以只写 yield 而代码仍然有效。这是为什么? yield 在这种情况下如何工作? import time from
假设我有一个上下文管理器: @contextmanager def cm(x): y = f(x) z = yield y g(z) 如何将 z 发送到上下文管理器? 我试过:
我使用 Python2.7 并且我想要函数:contextlib.redirect_stdout . 我的意思是,我想重定向特定函数的输出(不是所有程序)。 问题是 - 只有 Python3 支持“c
作为将我的游戏引擎代码转换为 cython 的一部分,我正在移植我的顶点缓冲区对象 (Vbo) 类。我使用这个 Vbo 类将 3D 模型数据发送到 GPU。代码 (vbo.pyx) 当前如下所示: c
我在 python 中使用 with 语句( PEP 343 ) 时遇到了一些问题,以便在上下文之后自动管理资源清理。特别是,with 语句 始终假定资源清理方法是 .close()。 IE。在下面的
为了以编程方式组合上下文管理器,我使用以下代码: == helpers.py == from contextlib import nested import mock def multiple_pat
context.nested 已被弃用,我试图理解这背后的基本原理,在阅读了很长时间的文档后,我看不到一个例子来说明第二个问题: Secondly, if the __enter__() method
我真的很喜欢“with open('in_file'') as f”这个语法。我想将该语法用于必须打开和关闭的我自己的资源。 但是,我不明白如何更改我的 open() 方法以启用“with”语法。我可
from contextlib import closing def init_db(): with closing(connect_db()) as db: with app
尝试从 docker 运行命令时,我遇到了这个错误 google 计算引擎上的 docker 容器。 这是堆栈跟踪: Traceback (most recent call last): File
为了以编程方式组合上下文管理器,我使用以下代码: == helpers.py == from contextlib import nested import mock def multiple_pat
为了说明我的问题,这里有一个不使用 contextlib 的基本请求: import urllib.request url = "http://www.example.com/"
在寻找性能错误的过程中,我终于确定问题的根源是 contextlib 包装器。开销相当惊人,我没想到这是减速的根源。减速在 50 倍的范围内,我无法承受循环。如果它有可能显着减慢速度,我肯定会感谢文档
为什么要使用 contextlib.suppress 来抑制异常,而不是使用 try/except 和 pass? 这两种方法在字符数量上没有区别(如果有的话,suppress 有更多的字符),即使代
我是一名优秀的程序员,十分优秀!