Lấy ví dụ tối thiểu sau đây:“Không thể khởi tạo lớp trừu tượng ... với các phương pháp trừu tượng” trên lớp học mà không cần phải có bất kỳ phương pháp trừu tượng
import abc
class FooClass(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def FooMethod(self):
raise NotImplementedError()
def main():
derived_type = type('Derived', (FooClass,), {})
def BarOverride(self):
print 'Hello, world!'
derived_type.FooMethod = BarOverride
instance = derived_type()
Chạy main()
giúp bạn:
TypeError: Can't instantiate abstract class Derived with abstract methods FooMethod
(Ngoại lệ xảy ra trên dòng instance = derived_type()
.)
Nhưng FooMethod
không được trừu tượng: Tôi đã ghi đè nó bằng BarOverride
. Vậy tại sao ngoại lệ này lại tăng lên?
Tuyên bố từ chối trách nhiệm: Có, tôi có thể sử dụng cú pháp rõ ràng class
và thực hiện chính xác điều tương tự. (Và thậm chí tốt hơn, tôi có thể làm cho nó hoạt động!) Nhưng đây là một trường hợp thử nghiệm tối thiểu, và ví dụ lớn hơn là tự động tạo các lớp. :-) Và tôi tò mò là tại sao điều này không hoạt động.
Edit: Và để ngăn chặn sự rõ ràng không phải là câu trả lời khác: Tôi không muốn vượt qua BarOverride
trong đối số thứ ba để type
: Trong ví dụ thực tế, BarOverride
cần có derived_type
ràng buộc với nó. Sẽ dễ dàng hơn nếu tôi có thể xác định BarOverride
sau khi tạo derived_type
. (Nếu tôi không thể làm được điều này, thì tại sao?)
Các tính trừu tượng của một lớp được xác định trong quá trình thi lớp . Tại sao bạn không đơn giản bao gồm 'FooMethod' trong từ điển trong khi tạo lớp? –
@SvenMarnach: 'BarOverride', trong ví dụ thực, cần phải có lớp dẫn xuất ràng buộc với nó. Tạo hàm sau đó là cách dễ nhất để thực hiện việc này. – Thanatos
Tôi không hiểu điểm đó. Bạn có ý nghĩa gì bởi "cần phải có lớp dẫn xuất ràng buộc với nó"? –