Błąd ten jest spowodowany tym wierszu:
with urlopen('https://www.python.org') as story:
Aby rozwiązać ten problem, należy wymienić tę linię z następującej linii:
story = urlopen('https://www.python.org')
Dodatkowe informacje o th e błąd
Dlaczego tak się dzieje?
Aby wykonać instrukcję with ... as
dla obiektu, należy zaimplementować menedżera kontekstów dla tego obiektu. Co to oznacza, że obiekt/klasa musi mieć zdefiniowane dla niego metody.
AttributeError
podniesiono, ponieważ nie ma żadnych menedżer kontekst wdrożony urlopen
(tj nie ma __enter__
i __exit__
metod zdefiniowanych dla niego).
Ponieważ autor urlopen
nie wdrożył, że nie wiele można zrobić, z wyjątkiem:
- albo nie używać
with...as
oświadczenie.
- lub, jeśli musisz, możesz użyć
contextlib.closing
(dzięki @vaultah, który dostarczył to rozwiązanie w komentarzach poniżej). Automatycznie implementuje menedżera kontekstu dla dowolnego obiektu, dzięki czemu można użyć instrukcji with...as
.
Jak zaimplementować menedżera kontekstu?
Można zaimplementować menedżera kontekstów, definiując metody obiektu/klasy: __enter__
i __exit__
.
Czytać these docs on context managers.
Przykład:
# example without a context manager
# will raise AttributeError
>>> class Person(object):
def __init__(self, name):
self.name = name
>>> with Person("John Doe") as p:
print p.name
>>> AttributeError: __exit__
Powyżej dostaliśmy AttributeError
ponieważ nie wdrożyły menedżera kontekstowe Person
. Poniżej znajduje się sposób implementacji menedżera kontekstów.
# implementing context manager
>>> class Person(object):
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"
[Kolejne możliwe rozwiązanie] (https://docs.python.org/2/library/contextlib.html#contextlib.closing). Byłoby wspaniale, gdybyś mógł wyjaśnić przyczynę błędu. – vaultah
@vaultah Zaktualizowano odpowiedź. – xyres