2015-06-03 12 views
9
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) 

Błąd:Traceback: AttributeError: addinfourl instancja ma atrybut '__exit__' wiadomość

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: addinfourl instance has no attribute '__exit__' 

ja nie rozumiejąc, co się dzieje z powyższym kodzie i jak go rozwiązać?

Informacje o systemie: python 2.7 w wirtualnym oknie Oracle ubuntu.

Odpowiedz

54

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:

  1. albo nie używać with...as oświadczenie.
  2. 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" 
+1

[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

+3

@vaultah Zaktualizowano odpowiedź. – xyres

-2

Można spróbować wykonać następujące czynności w Pythonie 2.7:

from urllib import urlopen 
story = urlopen('https://www.python.org') 
story_words = [] 
for line in story: 
    line_words = line.split() 
    for words in line_words: 
     story_words.append(words) 
+2

OP: Dlaczego oznaczono to jako odpowiedź? [Odpowiedź xyresa] (http://stackoverflow.com/a/30628142/257924) faktycznie odpowiada na pytanie dlaczego. – bgoodr

Powiązane problemy