我非常喜欢语法" open(' in_file'')为f"。 我想将这种语法用于我自己的资源,必须打开和关闭。
但是,我不明白如何更改我的open()方法以启用''句法。 我可以(并且确实)使用contextlib.closing()方法,但重复使用后会变得有点笨重。
因此,我将在下面提出有关shelve.open()的问题。 我不是建议更改搁置模块,而是使用它,因为源代码随时可供所有人使用。
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()方法,可以使用或不使用'来调用。
因此,要成功回答这个问题,您需要获取搁置模块的源代码,并显示需要对shelve.open()进行哪些更改以使单个方法可以使用或不使用'与' (比如内置的open()或Python3的urllib.urlopen())。
答案 0 :(得分:2)
这里最大的问题是如果你做了
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
功能。