2015-06-03 16 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) 

Thông báo lỗi:Traceback: AttributeError: addinfourl dụ không có thuộc tính '__exit__'

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

Tôi không hiểu được điều gì xảy ra với đoạn code trên và làm thế nào để giải quyết nó?

Thông tin hệ thống: python 2.7 trong hộp ảo ubuntu oracle.

Trả lời

54

lỗi đó là do dòng này:

with urlopen('https://www.python.org') as story: 

Để sửa lỗi này, thay thế dòng với dòng sau:

story = urlopen('https://www.python.org') 

Thông tin bổ sung về thứ e error

Tại sao điều này xảy ra?

Để thực hiện công việc tuyên bố with ... as cho một đối tượng, trình quản lý ngữ cảnh cho đối tượng đó phải được triển khai. Điều đó có nghĩa là đối tượng/lớp học phải có các phương thức __enter____exit__ được xác định cho nó.

Các AttributeError được nuôi nấng bởi vì không có bất kỳ nhà quản lý bối cảnh thực hiện cho urlopen (ví dụ nó không có __enter____exit__ phương pháp định nghĩa cho nó).

Kể từ khi tác giả của urlopen đã không được thực hiện điều đó, không có nhiều bạn có thể làm gì về nó, ngoại trừ:

  1. hoặc không sử dụng with...as tuyên bố.
  2. hoặc, nếu bạn phải, bạn có thể sử dụng contextlib.closing (nhờ @vaultah đã cung cấp giải pháp này trong các nhận xét bên dưới). Nó tự động triển khai trình quản lý ngữ cảnh cho bất kỳ đối tượng nào, do đó cho phép bạn sử dụng câu lệnh with...as.

Làm cách nào để triển khai trình quản lý ngữ cảnh?

Bạn có thể triển khai trình quản lý ngữ cảnh bằng cách xác định phương thức __enter____exit__ cho đối tượng/lớp.

Đọc these docs on context managers.

Ví dụ:

# 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__ 

Ở trên, chúng tôi đã nhận một AttributeError vì chúng ta đã không thực hiện quản lý bối cảnh cho Person. Dưới đây là cách trình quản lý ngữ cảnh được triển khai.

# 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

[Một giải pháp khác có thể] (https://docs.python.org/2/library/contextlib.html#contextlib.closing). Sẽ là tuyệt vời nếu bạn có thể giải thích lý do cho lỗi. – vaultah

+3

@vaultah Đã cập nhật câu trả lời. – xyres

-2

Bạn có thể thử cách sau bằng Python 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: Tại sao điều này được đánh dấu là câu trả lời? [Câu trả lời của xyres] (http://stackoverflow.com/a/30628142/257924) thực sự trả lời câu hỏi tại sao. – bgoodr

Các vấn đề liên quan