What is generics in python

Python Generics

One of the new features of Python 3.10 is TypeAlias. The example given is as follows.

StrCache = 'Cache[str]' # a type alias LOG_PREFIX = 'LOG[DEBUG]' # a module constant 
StrCache: TypeAlias = 'Cache[str]' # a type alias LOG_PREFIX = 'LOG[DEBUG]' # a module constant 

This makes StrCache more of a type alias than a string variable that clearly looks like Cache[str] (which it is).

This article is not about TypeAlias per se, but rather about Cache[str] , which shows that Python seems to support Java-like generics, like Python’s built-in support for List[str] or list[str].

So let’s see how Python can implement a Cache[str] Cache that can only hold strings, but not other types.

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 
 from typing import TypeVar, Generic  T = TypeVar('T')  class Cache(Generic[T]):  def __init__(self) -> None:  self.items: dict[str, T] = <>   def put(self, key: str, item: T) -> None:  self.itemsWhat is generics in python = item # Line 13   def get(self, key: str) -> T:  return self.items.get(key) 

We are still using Python’s typing module, so the above code is still in the realm of class type hints, which is not a constraint on the Python interpreter and only affects checking tools like mypy.

cache = Cache[str]()  cache.put('a', 'abc') print(cache.get('a'))  cache.put('b', 123) # Line 21 print(cache.get('b')) 

The command python test.py works fine and the output is as follows.

Читайте также:  Python print bin string

But in IntelliJ IDEA, the fifth line above, the cache.put(‘b’, 123) line, prompts:

Expected type 'str' (matched generic type 'T'), got 'int' instead 

If you use mypy to detect.

$ mypy tt.py tt.py:13: error: Incompatible return value type (got "Optional[T]", expected "T") tt.py:21: error: Argument 2 to "put" of "Cache" has incompatible type "int"; expected "str" Found 2 errors in 1 file (checked 1 source file) 

In addition to Generic, TypeVar used above, typing module has more type constraints like Mapping, Iterator, Sequence and more Java-like generic functions.

Generic subtypes

 1  2  3  4  5  6  7  8  9 10 
from typing import TypeVar, Generic  T = TypeVar('T')  class Cache(Generic[T]):  pass  class TTLCache(Cache[T]):  pass 

Generic functions

from typing import TypeVar, Sequence  T = TypeVar('T') # Declare type variable  def first(seq: Sequence[T]) -> T: # Generic function  return seq[0] 

There are more uses than can be listed here. The need to write your own implementation code using generics is not really big, unless you do a third-party generic library that will use generic writing, which makes it clearer for others to use.

Источник

Python Generic Types: Tutorial & Examples

This concise article is about generic types in Python.

Overview

Generic types allow us to define classes, functions, or methods that can work with different data types without specifying the exact data type beforehand. This is useful when we want to create a single implementation that can handle multiple data types.

To define generic types in Python, we can use the built-in module typing , which provides a set of type hints for Python 3.5 and newer. The typing module defines a number of generic types, such as List , Tuple , Dict , and Union, which can be used to define generic functions, methods, and classes.

Читайте также:  Html css сортировка таблицы

Words might be boring and vague; let’s examine the following practical examples for a better understanding.

Examples

Generic Function

In this basic example, we’ll define a generic function that can work with different types of lists:

from typing import List, TypeVar T = TypeVar('T') def reverse_list(lst: List[T]) -> List[T]: return lst[::-1] # Example usage num_lst = [1, 2, 3, 4, 5] str_lst = ['a', 'b', 'c', 'd', 'e'] print(reverse_list(num_lst)) print(reverse_list(str_lst))

Basic Generic Class

This example is a little bit more advanced than the first one (but still simple in comparison to the later ones). We’ll define a generic class that can work with different types of values:

from typing import TypeVar T = TypeVar('T') class Box: def __init__(self, value: T): self.value = value def get_value(self) -> T: return self.value # Example usage box1 = Box(10) box2 = Box('Sling Academy') print(box1.get_value()) print(box2.get_value()) 

Generic Dictionaries

In this example, we’ll create a generic method that can work with different types of dictionaries:

from typing import Dict, TypeVar K = TypeVar('K') V = TypeVar('V') def print_dict(dct: Dict[K, V]) -> None: for key, value in dct.items(): print(f': ') # Example usage num_dict = str_dict = print_dict(num_dict) print_dict(str_dict) 
1: one 2: two 3: three a: 1 b: 2 c: 3

Generic Data Repository Class

This example demonstrates a more advanced use case of generic types in Python. We’ll make a generic data repository class that can work with different data types.

from typing import TypeVar, Generic, List T = TypeVar('T') class DataRepository(Generic[T]): def __init__(self): self.data = [] def add_data(self, item: T) -> None: self.data.append(item) def remove_data(self, item: T) -> None: self.data.remove(item) def get_all_data(self) -> List[T]: return self.data # Example usage repo = DataRepository[int]() repo.add_data(10) repo.add_data(20) repo.add_data(30) print(repo.get_all_data()) # Output: [10, 20, 30] repo.remove_data(20) print(repo.get_all_data()) # Output: [10, 30] repo2 = DataRepository[str]() repo2.add_data('apple') repo2.add_data('banana') repo2.add_data('orange') print(repo2.get_all_data()) # Output: ['apple', 'banana', 'orange'] repo2.remove_data('banana') print(repo2.get_all_data()) # Output: ['apple', 'orange']

Our DataRepository class uses a generic type T to define the type of data that the repository can store. The generic type T ensures that the data added to the repository is of the correct type, and the generic return type List[T] ensures that the data retrieved from the repository is of the correct type, too.

Читайте также:  Learning JavaScript

Benefits of Using Generic Types

Benefits of using generic types include increased flexibility and reusability of code, improved type safety and clarity, and reduced development time.

Источник

Оцените статью