self.__class__
là tham chiếu đến loại loại của phiên bản hiện tại.
Đối với trường hợp của abstract1
, mà muốn được là abstract1
lớp tự, đó là những gì bạn không muốn có một lớp trừu tượng. lớp trừu tượng chỉ có nghĩa là để được subclassed, không để tạo ra các trường hợp trực tiếp:
>>> abstract1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
NotImplementedError: Interfaces can't be instantiated
Đối với một thể hiện của một lớp con của abstract1
, self.__class__
sẽ là một tham chiếu đến lớp con cụ thể:
>>> class Foo(abstract1): pass
...
>>> f = Foo()
>>> f.__class__
<class '__main__.Foo'>
>>> f.__class__ is Foo
True
Việc ném một ngoại lệ ở đây giống như sử dụng câu lệnh assert
ở nơi khác trong mã của bạn, nó bảo vệ bạn khỏi những sai lầm ngớ ngẩn.
Lưu ý rằng pythonic cách để kiểm tra cho các loại một thể hiện là sử dụng type()
function thay vào đó, cùng với một sắc thử nghiệm với is
điều hành:
class abstract1(object):
def __init__(self):
if type(self) is abstract1:
raise NotImplementedError("Interfaces can't be instantiated")
Có rất ít điểm trong bằng cách sử dụng một bài kiểm tra bình đẳng ở đây như đối với các lớp tùy chỉnh, __eq__
về cơ bản được triển khai như một bài kiểm tra nhận dạng.
Python cũng bao gồm thư viện chuẩn để xác định các lớp cơ sở trừu tượng, được gọi là abc
. Nó cho phép bạn đánh dấu các phương thức và thuộc tính là trừu tượng và sẽ từ chối tạo các cá thể của bất kỳ lớp con nào chưa định nghĩa lại các tên đó.
Nguồn
2013-12-19 17:52:50
Tôi nghĩ điều này đòi hỏi nhiều ngữ cảnh hơn. Bạn đã "tìm" mã này ở đâu? Nó cơ bản bị hỏng. – Iguananaut
@Iguananaut: Tại sao nó bị hỏng? Nó hoạt động * tốt * khi được sử dụng như dự định; như một lớp cơ sở trừu tượng. –
Tôi khá chắc chắn trước đó nó là một cái gì đó khác nhau? Tôi không biết - Tôi đồng ý, những gì trên đó bây giờ không bị hỏng. – Iguananaut