Original link: https://www.kingname.info/2022/05/29/any-vs-typevar/
I believe that many students will use type annotations to improve the readability of the code when writing Python, and also help the IDE to achieve automatic completion.
Suppose we now get an object, this object may be a list or a generator, I write a function to get its first element. The code is simple:
1 |
from typing import Iterator |
The code is written, but when I get the first element and want to print the data in it, I find that I forgot what properties the People class has, and at this time, the auto-completion of PyCharm also fails, and I cannot It is very inefficient to not turn the code back to find the location defined by People. As shown below.
If we use type annotations, we can solve this problem:
Everyone knows this routine.
Now the question is, in addition to the People
class, we also have the Cat
class, and the elements in the list may all be instances of the People
class, or they may all be instances of the Cat
class. What should we do in this situation?
First of all, you have encountered the first problem, how to write the type annotation of the parameter of get_first_element
?
You might write something like this:
1 |
def get_first_element (ele_list: Union[List[Union[People, Cat]], Iterator[Union[People, Cat]]]) |
What if there is also a Dog
class?
To simplify things, you might use Any
, type, so get_first_element
becomes like this:
1 |
def get_first_element (ele_list: Union[List[Any], Iterator[Any]]) -> Optional[Any]: |
Now you find that the problem comes again, PyCharm’s autocompletion is broken again. Because Any is any type, it doesn’t actually know what you’re returning until the code runs. As shown below:
In this case, you need to use泛型
in Python type annotations. We know that generics are a concept in static languages, and Python also has types due to the use of type annotations. So the concept was borrowed.
Let’s see how to use it:
1 |
from typing import TypeVar |
Note that the variable name T
here and the parameter 'T'
of TypeVar can be written as arbitrary strings at the same time, but the variable name must be consistent with the parameter. E.g:
1 |
GodType = TypeVar( 'GodType' ) |
Then just use T as Any
. Let’s take a look at the effect:
As you can see, PyCharm can automatically complete again. Using TypeVar
, you can tell PyCharm that the returned type is the same as the type corresponding to T
in the incoming parameter. For example, in the incoming parameter, T
is in List[T]
or Generator[T]
, so the returned parameter needs to be consistent with the elements in the list or the element type in the generator.
Let’s test it with the Cat generator and find that it can also be autocompleted:
What’s more, what if there are instances of Cat
and instances of People
in my list? At this time, PyCharm will directly list the possible completions of the two instances for you:
This article is reprinted from: https://www.kingname.info/2022/05/29/any-vs-typevar/
This site is for inclusion only, and the copyright belongs to the original author.