Được coi là hình thức xấu để nâng cao ngoại lệ trong __init__
? Nếu vậy, phương thức ném lỗi được chấp nhận là gì khi các biến lớp nhất định được khởi tạo là None
hoặc không đúng loại?
Được coi là hình thức xấu để nâng cao ngoại lệ trong __init__
? Nếu vậy, phương thức ném lỗi được chấp nhận là gì khi các biến lớp nhất định được khởi tạo là None
hoặc không đúng loại?
Câu trả lời:
Tăng ngoại lệ trong __init__()
là hoàn toàn tốt. Không có cách nào khác tốt để chỉ ra một điều kiện lỗi trong hàm tạo và có hàng trăm ví dụ trong thư viện chuẩn nơi xây dựng một đối tượng có thể đưa ra một ngoại lệ.
Lớp lỗi để nâng, tất nhiên, là tùy thuộc vào bạn. ValueError
là tốt nhất nếu hàm tạo được truyền tham số không hợp lệ.
ValueError
và TypeError
.
__init__
không phải là nhà xây dựng, đó là intializer. Bạn có thể muốn chỉnh sửa dòng Không có cách nào khác tốt để chỉ ra tình trạng lỗi trong hàm tạo, ..
Đúng là cách thích hợp duy nhất để chỉ ra lỗi trong hàm tạo là đưa ra một ngoại lệ. Đó là lý do tại sao trong C ++ và trong các ngôn ngữ hướng đối tượng khác được thiết kế có tính an toàn ngoại lệ, hàm hủy sẽ không được gọi nếu một ngoại lệ được ném vào hàm tạo của một đối tượng (có nghĩa là việc khởi tạo đối tượng không đầy đủ). Đây thường không phải là trường hợp trong các ngôn ngữ kịch bản, chẳng hạn như Python. Ví dụ: đoạn mã sau ném AttributionError nếu socket.connect () không thành công:
class NetworkInterface:
def __init__(self, address)
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.connect(address)
self.stream = self.socket.makefile()
def __del__(self)
self.stream.close()
self.socket.close()
Lý do là hàm hủy của đối tượng không hoàn chỉnh được gọi sau khi thử kết nối không thành công, trước khi thuộc tính luồng được khởi tạo. Bạn không nên tránh ném ngoại lệ từ các nhà xây dựng, tôi chỉ nói rằng thật khó để viết mã an toàn ngoại lệ hoàn toàn bằng Python. Một số nhà phát triển Python tránh sử dụng các hàm hủy hoàn toàn, nhưng đó là vấn đề của một cuộc tranh luận khác.
__del__
vì nó được viết xấu. Bạn sẽ có chính xác vấn đề tương tự nếu bạn đã làm this->p_socket->close()
trong một hàm hủy trong C ++. Trong C ++, bạn sẽ không làm điều đó - bạn sẽ để đối tượng thành viên tự hủy. Làm tương tự trong trăn.
Tôi không thấy bất kỳ lý do nào mà nó phải là hình thức xấu.
Ngược lại, một trong những điều ngoại lệ được biết là hoạt động tốt, trái ngược với việc trả lại mã lỗi, là mã lỗi thường không thể được trả về bởi các nhà xây dựng. Vì vậy, ít nhất là trong các ngôn ngữ như C ++, nâng cao ngoại lệ là cách duy nhất để báo hiệu lỗi.
Tôi đồng tình với tất cả những điều trên.
Thực sự không có cách nào khác để báo hiệu rằng có gì đó không ổn trong việc khởi tạo một đối tượng ngoài việc đưa ra một ngoại lệ.
Trong hầu hết các lớp chương trình trong đó trạng thái của một lớp hoàn toàn phụ thuộc vào các đầu vào của lớp đó, chúng ta có thể mong đợi một loại ValueError hoặc TypeError được nâng lên.
Các lớp có hiệu ứng phụ (ví dụ: lớp có kết nối mạng hoặc đồ họa) có thể gây ra lỗi trong init nếu (ví dụ) thiết bị mạng không khả dụng hoặc không thể ghi đối tượng canvas. Điều này nghe có vẻ hợp lý với tôi bởi vì bạn thường muốn biết về điều kiện thất bại càng sớm càng tốt.