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)
Error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: addinfourl instance has no attribute '__exit__'
I am not understanding what's wrong with the above code and how to resolve it?
System information : python 2.7 in ubuntu oracle virtual box.
That error is caused by this line:
with urlopen('https://www.python.org') as story:
You can't use any random object in a with...as
statement.
There are two ways to fix this:
Solution 1: Use contextlib.closing
:
from contextlib import closing
with closing(urlopen('https://www.python.org')) as story:
...
Solution 2: Don't use a with...as
statement; instead assign the value to a variable:
story = urlopen('https://www.python.org')
...
You can't use any random object in a with ... as
statement.
Only those objects will work which have two magic methods: __enter__
and __exit__
implemented on them. Collectively, these methods are called "context manager". An introductory tutorial about this can be found below.
The AttributeError
was raised because there isn't any context manager implemented for urlopen
(i.e. it doesn't have __enter__
and __exit__
methods defined for it).
This leaves you with two choices:
with...as
statement.contextlib.closing
(thanks to @vaultah who provided this solution in a comment below). It automatically implements context manager for any object, thereby allowing you to use with...as
statement.(Note: In Python 3, urlopen
does have a context manager, and thus can be used in a with...as
statement.)
To make an object work in a with...as
statement, you first need to implement the context manager for that object. In simpler terms, you need to define __enter__
and __exit__
methods for that object/class.
Do read these docs on context managers.
Example:
>>> 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With