2011-10-31 31 views
7

Có gì sai với đoạn mã sau (dưới Python 2.7.1):Lỗi ngoại lệ phải bắt nguồn từ BaseException ngay cả khi nó (Python 2.7)

class TestFailed(BaseException): 
    def __new__(self, m): 
     self.message = m 
    def __str__(self): 
     return self.message 

try: 
    raise TestFailed('Oops') 
except TestFailed as x: 
    print x 

Khi tôi chạy nó, tôi nhận được:

Traceback (most recent call last): 
    File "x.py", line 9, in <module> 
    raise TestFailed('Oops') 
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType 

Nhưng có vẻ với tôi rằng TestFailed có nguồn gốc từ BaseException.

+0

Đối với những người khác không thể hiểu tại sao họ gặp phải lỗi này: hãy kiểm tra để đảm bảo bạn không vô tình thực hiện 'def MyException (Ngoại lệ): pass' thay vì' class MyException bắt buộc (Ngoại lệ)): pass'. Lỗi dễ dàng để bỏ lỡ. –

Trả lời

9

__new__ là một staticmethod mà cần phải trả lại một ví dụ.

Thay vào đó, sử dụng các phương pháp __init__:

>>> class TestFailed(Exception): 
    def __init__(self, m): 
     self.message = m 
    def __str__(self): 
     return self.message 

>>> try: 
    raise TestFailed('Oops') 
except TestFailed as x: 
    print x 


Oops 
+0

Cảm ơn (và những người khác đã trả lời). Tôi khá nghi ngờ rằng nó là một cái gì đó đơn giản (nhưng tôi không có nhiều kinh nghiệm với Python chính nó). –

4

Sử dụng __init__() thay vì __new__() để "khởi tạo" các lớp học. Trong hầu hết các trường hợp, việc ghi đè __new__ là không cần thiết. Nó được gọi trước __init__ trong khi tạo đối tượng.

Xem thêm Python's use of __new__ and __init__?

2

Việc thực hiện __new__ nên trở về một thể hiện của lớp, nhưng nó hiện đang trở None (theo mặc định).

Tuy nhiên, có vẻ như bạn nên sử dụng __init__ tại đây, thay vì __new__.

11

Những người khác đã cho các bạn làm thế nào để sửa chữa thực hiện của bạn, nhưng tôi cảm thấy điều quan trọng chỉ ra rằng hành vi mà bạn đang thực hiện đã là hành vi tiêu chuẩn của trường hợp ngoại lệ trong Python vì vậy hầu hết các mã của bạn là hoàn toàn không cần thiết. Chỉ xuất phát từ Exception (lớp cơ sở thích hợp cho các ngoại lệ thời gian chạy) và đặt pass làm cơ thể.

class TestFailed(Exception): 
    pass 
+0

Cảm ơn thông tin. Tôi không biết điều đó. (Trong trường hợp cụ thể này, mã được đăng ở đây được đơn giản hóa và '__init__' thực sự của tôi có một số đối số bổ sung. Nhưng tôi chắc chắn sẽ sử dụng thông tin của bạn trong tương lai.) –

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