搁置模块不适用于"with"语句



我正在尝试在python中使用搁置模块,并且我正在尝试将其与"with"语句结合使用,但是在尝试这样做时,我收到以下错误:

with shelve.open('shelve', 'c') as shlv_file:
shlv_file['title']    = 'The main title of my app'
shlv_file['datatype'] = 'data type int32'
shlv_file['content']  = 'Lorem ipsum'
shlv_file['refs']     = '<htppsa: asda.com>'
print(shlv_file)

引发以下错误:

with shelve.open('shelve', 'c') as shlv_file:
AttributeError: DbfilenameShelf instance has no attribute '__exit__'

虽然这样做:

shlv_file = shelve.open('data/shelve', 'c')
shlv_file['title']    = 'The main title of my app'
shlv_file['datatype'] = 'data type int32'
shlv_file['content']  = 'Lorem ipsum'
shlv_file['refs']     = '<htppsa: asda.com>'
shlv_file.close()
shlv_file = shelve.open('data/shelve', 'c')
shlv_file['new_filed'] = 'bla bla bla'
print(shlv_file)

不会引发任何错误,并且输出是预期的输出。第一种语法有什么问题?我正在观看一个 python 课程,其中讲师毫无问题地使用第一个版本。

您需要了解with的目的是什么。它基本上用于自动处理调用它的对象的设置和清理,前提是这些对象支持使用此类设置和清理功能。特别是,设置的对象是__enter__函数,拆卸等效项是__exit__函数。下面是一个示例:

In [355]: class Foo():
...:     def __enter__(self):
...:         print("Start!")
...:         return self
...:     def __exit__(self, type, value, traceback):
...:         print("End!")
...:         

并且,现在使用with...as实例化一个Foo对象:

In [356]: with Foo() as x:
...:     print(x)
...:     
Start!
<__main__.Foo object at 0x1097f5da0>
End!

如您所见,with...as将强制调用这些设置/拆卸方法,如果缺少这些方法,则会引发AttributeError,因为尝试调用不存在的实例方法。

您的shelve对象也是如此 - 它的类中没有定义__exit__方法,因此使用with将不起作用。


根据文档,从版本 3.4 及更高版本添加了对上下文管理器的支持。如果上下文管理器不起作用,则意味着您的版本较旧。

最新更新