iT邦幫忙

0

Python 裝飾器 (decorator) @abstractmethod

  • 分享至 

  • xImage
  •  

@abstractmethod 是 Python 標準庫中的一個裝飾器,位於 abc 模組內,用來定義 抽象方法 (abstract methods)。抽象方法是指必須在子類別中實作的方法,而在基類 (abstract base class, ABC) 中只能定義方法名稱和規範,不能有具體的實作內容。

使用 @abstractmethod 可以確保某些方法在子類別中被實作,否則子類別無法被實例化。

  1. 為什麼使用 @abstractmethod?
  • 強制規範子類別行為:定義出子類別必須實作的方法,確保程式的一致性。
  • 設計更清晰的接口:提供方法簽名的模板,指導子類別的開發。
  • 避免基類被實例化:基類僅作為框架存在,防止直接使用。
  1. @abstractmethod 的基本語法
    引入 ABC 和 @abstractmethod
  • ABC 是 Python 的內建抽象基類,它用來輔助定義抽象類別。
  • @abstractmethod 裝飾器標註抽象方法。
    範例
from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def sound(self):
        pass  # 不定義具體實作,只是聲明

    @abstractmethod
    def move(self):
        pass

# Animal 是抽象類別,無法直接實例化
# animal = Animal()  # TypeError: Can't instantiate abstract class Animal with abstract methods

子類別必須實作所有抽象方法,否則無法實例化

class Dog(Animal):
    def sound(self):
        return "Woof!"

    def move(self):
        return "Run"

dog = Dog()
print(dog.sound())  # Woof!
print(dog.move())   # Run
  1. 抽象類別中的具體方法
    抽象類別可以包含 具體方法,這些方法不需要在子類別中實作。只有被 @abstractmethod 標註的方法是必須實作的。

範例

class Shape(ABC):
    def description(self):
        return "This is a shape."

    @abstractmethod
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

rect = Rectangle(4, 5)
print(rect.description())  # This is a shape.
print(rect.area())         # 20
  1. @abstractmethod 與多型
    抽象基類通常用於設計多型行為。抽象方法定義了接口,允許不同的子類別在具體實作中表現出不同的行為。

範例

class Payment(ABC):
    @abstractmethod
    def pay(self, amount):
        pass

class CreditCardPayment(Payment):
    def pay(self, amount):
        return f"Paid {amount} using Credit Card."

class PayPalPayment(Payment):
    def pay(self, amount):
        return f"Paid {amount} using PayPal."

# 支付方式可依不同類別動態改變
def process_payment(payment: Payment, amount):
    print(payment.pay(amount))

process_payment(CreditCardPayment(), 100)  # Paid 100 using Credit Card.
process_payment(PayPalPayment(), 200)     # Paid 200 using PayPal.
  1. 子類別中使用 super() 與 @abstractmethod
    如果需要在子類別中擴展抽象基類的方法,可以使用 super() 調用基類的部分功能。

範例

class Animal(ABC):
    @abstractmethod
    def sound(self):
        pass

class Cat(Animal):
    def sound(self):
        super().sound()  # 調用基類的空方法(僅示例,實際基類方法通常有意義)
        return "Meow!"

cat = Cat()
print(cat.sound())  # Meow!
  1. 抽象屬性
    除了方法,@abstractmethod 也可以用來定義抽象屬性,這樣子類別需要提供具體的屬性值。

範例

class Vehicle(ABC):
    @property
    @abstractmethod
    def wheels(self):
        pass

class Car(Vehicle):
    @property
    def wheels(self):
        return 4

car = Car()
print(car.wheels)  # 4
  1. 常見問題
  • 為什麼基類無法實例化?
    如果基類中有未實作的抽象方法,則基類是抽象類別,無法直接使用。
  • 可以只實作部分抽象方法嗎?
    不行。子類別必須實作所有的抽象方法,否則子類別也會成為抽象類別,無法被實例化。
  • 抽象類別可以有初始化方法 (init) 嗎?
    可以,抽象類別的初始化方法可以用於設置通用屬性,並被子類別繼承。

總結

@abstractmethod 是 Python 中用來聲明抽象方法的裝飾器。
它強制子類別實作方法,確保程序設計的規範性和一致性。
抽象基類通常用於定義接口,促進多型行為。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言