Exemplo simples usando funções:

from typing import List, TypeVar
 
T = TypeVar("T")
 
def first(container: List[T]) -> T:
    return container[0]
  
if __name__ == "__main__":
    list_one: List[str] = ["a", "b", "c"]
    print(first(list_one))
    
    list_two: List[int] = [1, 2, 3]
    print(first(list_two))

Exemplo usando classes:

from logging import Logger
 
class LoggedVar[T]:
    def __init__(self, value: T, name: str, logger: Logger) -> None:
        self.name = name
        self.logger = logger
        self.value = value
 
    def set(self, new: T) -> None:
        self.log('Set ' + repr(self.value))
        self.value = new
 
    def get(self) -> T:
        self.log('Get ' + repr(self.value))
        return self.value
 
    def log(self, message: str) -> None:
        self.logger.info('%s: %s', self.name, message)

Para usar a classe, basta chama-la com o tipo:

my_log = LoggedVar[int](...)

Podemos herdar também:

class MySubLoggedVar(LoggedVar[int]):
	pass