> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Python Generic Class

A generic class in Python is a class that can be parameterized with one or more type variables, allowing it to operate on different data types while maintaining strict static type safety. By defining a class as generic, developers defer the specification of internal types until the class is instantiated, enabling static type checkers (like `mypy` or `pyright`) to enforce consistency across attributes, method arguments, and return values.

## Syntax and Implementation

Python provides two distinct syntaxes for defining generic classes, depending on the version.

### Modern Syntax (Python 3.12+)

Introduced in PEP 695, Python 3.12 natively supports type parameter syntax using square brackets directly in the class definition. This eliminates the need to import `TypeVar` or `Generic`.

```python theme={"dark"}
class Container[T]:
    def __init__(self, value: T) -> None:
        self.value: T = value

    def get_value(self) -> T:
        return self.value
```

### Legacy Syntax (Python 3.5 - 3.11)

In older versions, generic classes are constructed by instantiating `typing.TypeVar` and inheriting from `typing.Generic`.

```python theme={"dark"}
from typing import TypeVar, Generic

T = TypeVar('T')

class Container(Generic[T]):
    def __init__(self, value: T) -> None:
        self.value: T = value

    def get_value(self) -> T:
        return self.value
```

## Instantiation and Type Binding

When a generic class is instantiated, the type variable is bound to a concrete type. This binding can be explicit (using square brackets during instantiation) or implicit (inferred by the type checker based on the arguments passed to the constructor).

```python theme={"dark"}

# Explicit type binding
int_container = Container[int](10)


# Implicit type binding (inferred as Container[str])
str_container = Container("text")


# Static type checkers will flag this as an error:
int_container.value = "invalid" 
```

## Multiple Type Variables

Generic classes can be parameterized with multiple type variables to represent complex internal structures.

```python theme={"dark"}

# Python 3.12+
class Pair[K, V]:
    def __init__(self, first: K, second: V) -> None:
        self.first: K = first
        self.second: V = second


# Legacy
K = TypeVar('K')
V = TypeVar('V')

class Pair(Generic[K, V]):
    def __init__(self, first: K, second: V) -> None:
        self.first: K = first
        self.second: V = second
```

## Type Bounds and Constraints

Type variables within generic classes can be restricted to accept only specific types or subclasses of a specific type.

**Constrained Types:** The type variable must be exactly one of the specified types.

```python theme={"dark"}

# Python 3.12+
class NumericProcessor[T: (int, float)]:
    pass


# Legacy
T_Num = TypeVar('T_Num', int, float)
class NumericProcessor(Generic[T_Num]):
    pass
```

**Bound Types:** The type variable must be a subclass of a specific class.

```python theme={"dark"}
class Animal:
    pass


# Python 3.12+
class AnimalEnclosure[T: Animal]:
    pass


# Legacy
T_Animal = TypeVar('T_Animal', bound=Animal)
class AnimalEnclosure(Generic[T_Animal]):
    pass
```

## Variance

Variance dictates how subtyping between generic classes relates to subtyping between their type arguments.

* **Invariance:** `Container[int]` is not a subtype of `Container[float]`. This is the default behavior.
* **Covariance:** Subtype relationships are preserved. If `Dog` is a subtype of `Animal`, `Producer[Dog]` is a subtype of `Producer[Animal]`.
* **Contravariance:** Subtype relationships are reversed. `Consumer[Animal]` is a subtype of `Consumer[Dog]`.

**Python 3.12+ Syntax:**
Under PEP 695, variance is automatically inferred by static type checkers based on how the type parameter is utilized within the class (e.g., as a return type vs. an argument type).

```python theme={"dark"}

# Variance is automatically inferred
class Producer[T]:
    def produce(self) -> T:
        raise NotImplementedError

class Consumer[T]:
    def consume(self, item: T) -> None:
        raise NotImplementedError
```

**Legacy Syntax:**
In older versions, variance must be explicitly declared using the `covariant` or `contravariant` keyword arguments in `TypeVar`.

```python theme={"dark"}
T_co = TypeVar('T_co', covariant=True)
T_contra = TypeVar('T_contra', contravariant=True)

class Producer(Generic[T_co]):
    def produce(self) -> T_co:
        raise NotImplementedError

class Consumer(Generic[T_contra]):
    def consume(self, item: T_contra) -> None:
        raise NotImplementedError
```

## Subclassing Generic Classes

When inheriting from a generic class, the subclass can retain the generic nature, concretize the type variable, or introduce entirely new type variables.

**Retaining Generics:**

```python theme={"dark"}

# Python 3.12+
class AdvancedContainer[T](Container[T]):
    def process(self) -> T:
        raise NotImplementedError


# Legacy
class AdvancedContainer(Container[T]):
    def process(self) -> T:
        raise NotImplementedError
```

**Concretizing the Type:**

```python theme={"dark"}

# Python 3.12+ and Legacy
class StringContainer(Container[str]):
    def __init__(self, value: str) -> None:
        super().__init__(value)
```

**Introducing New Type Variables:**
A subclass can inherit a concretized type while introducing its own new type variables. In legacy syntax, this requires explicitly inheriting from `Generic` alongside the concretized base class.

```python theme={"dark"}

# Python 3.12+
class MappedStringContainer[V](Container[str]):
    def __init__(self, key: str, mapped_value: V) -> None:
        super().__init__(key)
        self.mapped_value: V = mapped_value


# Legacy
V = TypeVar('V')
class MappedStringContainer(Container[str], Generic[V]):
    def __init__(self, key: str, mapped_value: V) -> None:
        super().__init__(key)
        self.mapped_value: V = mapped_value
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Python Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
