Bre*_*tis 16 python python-2.7
from urllib import urlopen
with urlopen('https://www.python.org') as story:
story_words = []
for line in story:
line_words = line.split()
for words in line_words:
story_words.append(word)
Run Code Online (Sandbox Code Playgroud)
错误信息:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: addinfourl instance has no attribute '__exit__'
Run Code Online (Sandbox Code Playgroud)
我不明白上面的代码有什么问题以及如何解决它?
系统信息:ubuntu oracle虚拟盒中的python 2.7.
xyr*_*res 70
该错误是由此行引起的:
with urlopen('https://www.python.org') as story:
Run Code Online (Sandbox Code Playgroud)
要解决此问题,请使用以下行替换该行:
from contextlib import closing
with closing(urlopen('https://www.python.org')) as story:
...
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
要使with...as语句为对象起作用,必须实现该对象的上下文管理器.它的意思是,对象/类必须有contextlib.closing和with...as它定义的方法.
在with ... as有人提出,因为没有为实现任何情况管理器__enter__(即它没有__exit__和AttributeError它定义的方法).
由于作者urlopen尚未实现,除了以下内容之外,您无能为力:
__enter__声明.__exit__(感谢@vaultah,他在下面的评论中提供了此解决方案).它自动为任何对象实现上下文管理器,从而允许您使用with...as语句.如何实现上下文管理器?
您可以通过定义执行上下文管理contextlib.closing和with...as方法的对象/类.
请阅读有关上下文管理器的这些文档.
例:
story = urlopen('https://www.python.org')
...
Run Code Online (Sandbox Code Playgroud)
上面,我们得到了一个,urlopen因为我们还没有实现上下文管理器with...as.以下是上下文管理器的实现方式.
>>> class Person(object):
"""To implement context manager, just create two methods
__enter__ and __exit__.
"""
def __init__(self, name):
self.name = name
def __enter__(self):
# The value returned by this method is
# assigned to the variable after ``as``
return self
def __exit__(self, exc_type, exc_value, exc_traceback ):
# returns either True or False
# Don't raise any exceptions in this method
return True
>>> with Person("John Doe") as p:
print p.name
>>> "John Doe" #success
Run Code Online (Sandbox Code Playgroud)