Tôi có một phiên bản cũ của Python 3, và tôi là trên Linux thay vì một máy Mac, nhưng tôi đã có thể tái tạo một cái gì đó rất gần với lỗi của bạn:
IOError: telling position disabled by next() call
Một IO lỗi, không phải là lỗi OS, nhưng cũng không giống nhau. Thật kỳ lạ, tôi không thể gây ra nó bằng cách sử dụng open('a+', ...)
của bạn, nhưng chỉ khi mở tệp ở chế độ đọc: open('r+', ...)
.
Tiếp tục muddling điều là lỗi xuất phát từ _io.TextIOWrapper
, một lớp xuất hiện phải được xác định trong tập tin _pyio.py
Python ... Tôi nhấn mạnh "xuất hiện", bởi vì:
Các TextIOWrapper
ở chỗ tệp có các thuộc tính như _telling
mà tôi không thể truy cập trên đối tượng bất kỳ là đối tượng tự gọi là _io.TextIOWrapper
.
Lớp TextIOWrapper
trong _pyio.py
không phân biệt giữa tệp có thể đọc, ghi hoặc truy cập ngẫu nhiên. Cả hai đều phải hoạt động hoặc cả hai sẽ tăng cùng một số IOError
.
Bất kể, lớp TextIOWrapper
như mô tả trong tập tin _pyio.py
vô hiệu hóa các phương pháp tell
trong khi lặp đi lặp lại là cơ bản dở dang.Đây có vẻ là những gì bạn đang chạy vào (bình luận là của tôi):
def __next__(self):
# Disable the tell method.
self._telling = False
line = self.readline()
if not line:
# We've reached the end of the file...
self._snapshot = None
# ...so restore _telling to whatever it was.
self._telling = self._seekable
raise StopIteration
return line
Trong phương pháp tell
, bạn hầu như luôn luôn break
ra khỏi lặp trước khi nó đạt đến cuối của tập tin, để lại _telling
khuyết tật (False
):
Một cách khác để thiết lập lại _telling
là phương pháp flush
, nhưng nó cũng thất bại nếu gọi trong khi lặp đi lặp lại là cơ bản dở dang:
IOError: can't reconstruct logical file position
Các khoảng cách này, ít nhất là trên hệ thống của tôi, là để gọi seek(0)
trên TextIOWrapper
, mà khôi phục tất cả mọi thứ vào một trạng thái đã biết (và thành công gọi flush
trong món hời):
def tell(self, char=False):
t, lc = self.f.tell(), 0
self.f.seek(0)
for line in self.f:
if t >= len(line):
t -= len(line)
lc += 1
else:
break
# Reset the file iterator, or later calls to f.tell will
# raise an IOError or OSError:
f.seek(0)
if char:
return lc, t
return lc
Nếu đó không phải là giải pháp cho hệ thống của bạn, ít nhất nó có thể cho bạn biết nơi để bắt đầu tìm kiếm.
PS: Bạn nên cân nhắc luôn luôn trả về cả số dòng và độ lệch ký tự. Các hàm có thể trả về các kiểu hoàn toàn khác nhau rất khó giải quyết --- nó dễ dàng hơn rất nhiều cho người gọi để vứt đi giá trị mà người đó không cần.
Khó trả lời mà không thấy phần còn lại của lớp học. (Tôi không thể sao chép nó trên Linux chỉ bằng các hàm.) Bạn có thể muốn đọc lên các thuộc tính ['OSError'] (https://docs.python.org/3/library/exceptions.html#OSError) , có thể cung cấp cho bạn (và chúng tôi) một số thông tin bổ sung. Câu hỏi đầu tiên của tôi là, vì đây là lỗi _OS_: Hệ điều hành của bạn là gì? Ngoài ra (có thể liên quan): Tại sao/như thế nào bạn [mở tập tin trong chế độ phụ thêm] (https://docs.python.org/3/library/functions.html#open) và sau đó 'tìm kiếm' xung quanh bên trong nó? –
Tôi đang mở nó trong chế độ nối thêm vì, giả định rằng tệp không tồn tại trước khi cá thể được tạo. (như bạn đã biết, tôi chắc chắn, chế độ 'a' tạo tệp nếu nó chưa tồn tại). Tôi muốn có thể tiết kiệm không gian trong mã để có một kiểm tra nếu tập tin tồn tại. Hệ điều hành của tôi là Mac OS X Yosemite, nhưng tôi không nghĩ rằng nó có liên quan đến Apple. –