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__
và __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__
và __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ừ:
- hoặc không sử dụng
with...as
tuyên bố.
- 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__
và __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"
[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
@vaultah Đã cập nhật câu trả lời. – xyres