Tôi có thể đến từ một tư duy khác, chủ yếu là lập trình viên C++. Câu hỏi này phải làm với OOP trong Python và cụ thể hơn là các phương thức ảo thuần túy. Vì vậy, lấy mã tôi thích nghi từ this question Tôi đang xem xét mẫu cơ bản này.Có phải chức năng ảo thuần túy của Python có thể và/hoặc đáng giá không?
class Animal():
def speak(self):
print("...")
class Cat(Animal):
def speak(self):
print("meow")
class Dog(Animal):
def speak(self):
print("woof")
my_pets = [Dog(), Cat(), Dog()]
for _pet in my_pets:
_pet.speak()
Vì vậy, bạn thấy nó gọi hàm nói cho các lớp có nguồn gốc khác nhau. Bây giờ vấn đề của tôi là gõ vịt là tất cả tốt và tôi nghĩ rằng tôi đã nắm bắt nó. Tuy nhiên, có sai khi theo đuổi OOP nghiêm ngặt hơn trong Python không? Vì vậy, tôi đã xem số Abstract Base Classes và cụ thể là abstractmethod. Với tôi tất cả điều này dường như làm là cho phép tôi gọi phương thức lớp cơ sở với siêu. Có cách nào/lý do (trong Python) để làm cho speak()
tinh khiết như vậy mà thực hiện một động vật có nguồn gốc mà không nói sẽ ném một lỗi?
Đối số của tôi cho việc theo đuổi như vậy sẽ là khi viết mô-đun và khung mà bạn dự định mọi người phân lớp, điều này sẽ tự tài liệu cho họ thực tế là họ cần triển khai hàm. Một ý tưởng có lẽ rất xấu là một cái gì đó như thế này, có lớp cơ sở "tinh khiết" chức năng ném một ngoại lệ. Vấn đề là lỗi này được tìm thấy trong thời gian chạy!
class VirtualException(BaseException):
def __init__(self, _type, _func):
BaseException(self)
class Animal():
def speak(self):
raise VirtualException()
class Cat(Animal):
def speak(self):
print("meow")
class Dog(Animal):
def speak(self):
print("woof")
class Wildebeest(Animal):
def function2(self):
print("What!")
my_pets = [Dog(), Cat(), Dog(), Wildebeest()]
for _pet in my_pets:
_pet.speak()
Theo tôi thấy, những gì bạn mô tả chính xác là những gì 'abstractmethod' thực hiện. Bạn có thể làm rõ những gì bạn muốn 'abstractmethod' không cung cấp? Bạn sẽ không nhận được một giải pháp "biên dịch-thời gian" cho bất cứ điều gì, bởi vì Python không thực sự có một thời gian biên dịch theo nghĩa C++. Nhưng 'abstractmethod' cho phép bạn nhận được lỗi khi lớp được định nghĩa (trước khi nó được khởi tạo). – BrenBarn
@BrenBarn Xin lỗi vì tuyên bố vụng về. Tôi biết tôi sẽ không nhận được lỗi thời gian biên dịch. Nó chỉ là tốt đẹp để biết tôi có thể nhận được một lỗi khi đối tượng lớp cơ sở trừu tượng hoặc một đối tượng lớp dẫn xuất không hợp lệ được khởi tạo. Lỗi của tôi là sử dụng một trình thông dịch Python 3 làm abstractmethod xuất hiện để không làm gì cả vì tôi không định nghĩa lớp theo cách Python3 đúng. Xem câu trả lời được chấp nhận. – benzeno
Related: http://stackoverflow.com/questions/4714136/python-how-to-implement-virtual-methods/38717503 –