2
2
========
3
3
4
4
This section explains how you can define your own generic classes that take
5
- one or more type parameters, similar to built-in types such as ``List [X] ``.
5
+ one or more type parameters, similar to built-in types such as ``list [X] ``.
6
6
User-defined generics are a moderately advanced feature and you can get far
7
7
without ever using them -- feel free to skip this section and come back later.
8
8
@@ -13,8 +13,8 @@ Defining generic classes
13
13
14
14
The built-in collection classes are generic classes. Generic types
15
15
have one or more type parameters, which can be arbitrary types. For
16
- example, ``Dict [int, str] `` has the type parameters ``int `` and
17
- ``str ``, and ``List [int] `` has a type parameter ``int ``.
16
+ example, ``dict [int, str] `` has the type parameters ``int `` and
17
+ ``str ``, and ``list [int] `` has a type parameter ``int ``.
18
18
19
19
Programs can also define new generic classes. Here is a very simple
20
20
generic class that represents a stack:
@@ -28,7 +28,7 @@ generic class that represents a stack:
28
28
class Stack (Generic[T]):
29
29
def __init__ (self ) -> None :
30
30
# Create an empty list with items of type T
31
- self .items: List [T] = []
31
+ self .items: list [T] = []
32
32
33
33
def push (self , item : T) -> None :
34
34
self .items.append(item)
@@ -40,7 +40,7 @@ generic class that represents a stack:
40
40
return not self .items
41
41
42
42
The ``Stack `` class can be used to represent a stack of any type:
43
- ``Stack[int] ``, ``Stack[Tuple [int, str]] ``, etc.
43
+ ``Stack[int] ``, ``Stack[tuple [int, str]] ``, etc.
44
44
45
45
Using ``Stack `` is similar to built-in container types:
46
46
@@ -90,13 +90,16 @@ instantiation:
90
90
>> > print (Stack[int ]().__class__ )
91
91
__main__.Stack
92
92
93
- Note that built-in types :py:class: `list `, :py:class: `dict ` and so on do not support
94
- indexing in Python. This is why we have the aliases :py:class: `~typing.List `, :py:class: `~typing.Dict `
93
+ For Python 3.8 and lower, note that built-in types :py:class: `list `,
94
+ :py:class: `dict ` and so on do not support indexing in Python.
95
+ This is why we have the aliases :py:class: `~typing.List `, :py:class: `~typing.Dict `
95
96
and so on in the :py:mod: `typing ` module. Indexing these aliases gives
96
97
you a class that directly inherits from the target class in Python:
97
98
98
99
.. code-block :: python
99
100
101
+ >> > # Only relevant for Python 3.8 and below
102
+ >> > # For Python 3.9 onwards, prefer `list[int]` syntax
100
103
>> > from typing import List
101
104
>> > List[int ]
102
105
typing.List[int ]
@@ -121,7 +124,7 @@ non-generic. For example:
121
124
122
125
.. code-block :: python
123
126
124
- from typing import Generic, TypeVar, Mapping, Iterator, Dict
127
+ from typing import Generic, TypeVar, Mapping, Iterator
125
128
126
129
KT = TypeVar(' KT' )
127
130
VT = TypeVar(' VT' )
@@ -136,7 +139,7 @@ non-generic. For example:
136
139
137
140
items: MyMap[str , int ] # Okay
138
141
139
- class StrDict (Dict [str , str ]): # This is a non-generic subclass of Dict
142
+ class StrDict (dict [str , str ]): # This is a non-generic subclass of dict
140
143
def __str__ (self ) -> str :
141
144
return ' StrDict({} )' .format(super ().__str__ ())
142
145
@@ -284,15 +287,15 @@ For class methods, you can also define generic ``cls``, using :py:class:`Type[T]
284
287
285
288
.. code-block :: python
286
289
287
- from typing import TypeVar, Tuple, Type
290
+ from typing import TypeVar, Type
288
291
289
292
T = TypeVar(' T' , bound = ' Friend' )
290
293
291
294
class Friend :
292
295
other = None # type: Friend
293
296
294
297
@ classmethod
295
- def make_pair (cls : Type[T]) -> Tuple [T, T]:
298
+ def make_pair (cls : Type[T]) -> tuple [T, T]:
296
299
a, b = cls (), cls ()
297
300
a.other = b
298
301
b.other = a
@@ -345,8 +348,8 @@ Let us illustrate this by few simple examples:
345
348
346
349
.. code-block :: python
347
350
348
- def salaries (staff : List [Manager],
349
- accountant : Callable[[Manager], int ]) -> List [int ]: ...
351
+ def salaries (staff : list [Manager],
352
+ accountant : Callable[[Manager], int ]) -> list [int ]: ...
350
353
351
354
This function needs a callable that can calculate a salary for managers, and
352
355
if we give it a callable that can calculate a salary for an arbitrary
@@ -363,10 +366,10 @@ Let us illustrate this by few simple examples:
363
366
def rotate (self ):
364
367
...
365
368
366
- def add_one (things : List [Shape]) -> None :
369
+ def add_one (things : list [Shape]) -> None :
367
370
things.append(Shape())
368
371
369
- my_things: List [Circle] = []
372
+ my_things: list [Circle] = []
370
373
add_one(my_things) # This may appear safe, but...
371
374
my_things[0 ].rotate() # ...this will fail
372
375
@@ -532,7 +535,7 @@ Here's a complete example of a function decorator:
532
535
533
536
.. code-block :: python
534
537
535
- from typing import Any, Callable, TypeVar, Tuple, cast
538
+ from typing import Any, Callable, TypeVar, cast
536
539
537
540
F = TypeVar(' F' , bound = Callable[... , Any])
538
541
@@ -724,32 +727,32 @@ variables replaced with ``Any``. Examples (following :pep:`PEP 484: Type aliases
724
727
725
728
.. code-block :: python
726
729
727
- from typing import TypeVar, Iterable, Tuple, Union, Callable
730
+ from typing import TypeVar, Iterable, Union, Callable
728
731
729
732
S = TypeVar(' S' )
730
733
731
- TInt = Tuple [int , S]
734
+ TInt = tuple [int , S]
732
735
UInt = Union[S, int ]
733
736
CBack = Callable[... , S]
734
737
735
738
def response (query : str ) -> UInt[str ]: # Same as Union[str, int]
736
739
...
737
740
def activate (cb : CBack[S]) -> S: # Same as Callable[..., S]
738
741
...
739
- table_entry: TInt # Same as Tuple [int, Any]
742
+ table_entry: TInt # Same as tuple [int, Any]
740
743
741
744
T = TypeVar(' T' , int , float , complex )
742
745
743
- Vec = Iterable[Tuple [T, T]]
746
+ Vec = Iterable[tuple [T, T]]
744
747
745
748
def inproduct (v : Vec[T]) -> T:
746
749
return sum (x* y for x, y in v)
747
750
748
751
def dilate (v : Vec[T], scale : T) -> Vec[T]:
749
752
return ((x * scale, y * scale) for x, y in v)
750
753
751
- v1: Vec[int ] = [] # Same as Iterable[Tuple [int, int]]
752
- v2: Vec = [] # Same as Iterable[Tuple [Any, Any]]
754
+ v1: Vec[int ] = [] # Same as Iterable[tuple [int, int]]
755
+ v2: Vec = [] # Same as Iterable[tuple [Any, Any]]
753
756
v3: Vec[int , int ] = [] # Error: Invalid alias, too many type arguments!
754
757
755
758
Type aliases can be imported from modules just like other names. An
0 commit comments