I'm trying to create a base class that works for any CRUD in applications and I've seen the following implementation:
ModelType = TypeVar("ModelType", bound=Base)
CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)
UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel)
class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
def __init__(self, model: Type[ModelType]):
"""CRUD object with default methods to Create, Read, Update,
Delete (CRUD).
**Parameters**
* `model`: A SQLAlchemy model class
* `schema`: A Pydantic model (schema) class
"""
self.model = model
'...crud methods'`
Generic is a way to define an abstract class, containing the objects that are specified (in this case [ModelType,CreateSchemaType, UpdateSchemaType]) or what is the use of generic?
If your question is about the purpose of
typing.GenericI would suggest you read through PEP 484. It has a section dedicated to user defined generic classes with some examples specifically for this, but the entire document is worthwhile reading IMHO. If you are unsure about the entire concept of generic types, the Wikipedia articles on parametric polymorphism and generic programming might even be worth skimming.In very simple terms, you can use the
Genericbase class to define your own classes in a generic way, i.e. parameterized with regards to one or more type arguments. These type parameters are constructed viatyping.TypeVar. It is worth noting that in most cases these things are only relevant for the purposes of type safety, which is not really enforced by Python itself. Instead, static type checkers (most IDEs have them built-in) deal with those things.As to your example, it is entirely possible to define your class in a generic way and thus improve your own coding experience because you'll likely get useful auto-suggestions and warnings by your IDE. This only really becomes useful, if you use the type variables somewhere else throughout your class. Example:
A good type checker like
mypywill know, thatais of theSubtype and thus has thefoomethod, whereasbis of theBasetype and therefore does not. And it will know so just from the way we annotatedCRUDBase.PyCharm for example struggles with this (don't know why). Fortunately, we can help it out with explicit type annotations because we defined
CRUDBaseas a generic type:Notice that so far there is nothing particularly "abstract" about our
CRUDBase. It is fully self-contained and functioning like this (albeit not very useful yet).If you want a class to be an abstract base and not be directly instantiated, the
abcmodule provides you with the tools you need. You can define an abstract base class and abstract methods on it that all subclasses must implement. But I think it is clear now that this is a different concept. The idea is that an abstract class is not intended to be instantiated, only its subclasses are.I hope this helps point you in a few useful directions.