from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
# shape = Shape() # TypeError: Can't instantiate abstract classclass Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
def perimeter(self):
return 2 * 3.14159 * self.radius
class Rectangle(Shape):
def __init__(self, w, h):
self.w, self.h = w, h
def area(self):
return self.w * self.h
def perimeter(self):
return 2 * (self.w + self.h)
c = Circle(5)
print(c.area()) # 78.53975class DataProcessor(ABC):
@abstractmethod
def fetch_data(self):
pass
@abstractmethod
def parse_data(self, raw):
pass
# Non-abstract method — provides shared logic!
def process(self):
raw = self.fetch_data()
parsed = self.parse_data(raw)
return f'Processed: {parsed}'
class ApiProcessor(DataProcessor):
def fetch_data(self):
return '{"value": 42}'
def parse_data(self, raw):
import json
return json.loads(raw)['value']
print(ApiProcessor().process()) # 'Processed: 42'class Config(ABC):
@property
@abstractmethod
def max_connections(self):
pass
class DevConfig(Config):
@property
def max_connections(self):
return 5
class ProdConfig(Config):
@property
def max_connections(self):
return 100
# Missing @property would fail at instantiation!Create an abstract class `Notification` with abstract methods `send(self, message)` and `get_channel(self) -> str`, plus a concrete method `notify(self, message)` that prints `f'Sending via {self.get_channel()}: {message}'` then calls `self.send(message)`. Create `EmailNotification` and `SMSNotification` implementing both abstract methods. Demonstrate calling `notify()` on both.