mirror of https://github.com/tiangolo/fastapi.git
📝 Add docs in Python Types for Optional (#1377)
* docs: Fix pydantic example in python-types.md
* 📝 Update Python Types Intro to include Optional
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
This commit is contained in:
parent
4a5cda0d77
commit
745ab48d65
|
|
@ -144,15 +144,15 @@ You can use, for example:
|
|||
{!../../../docs_src/python_types/tutorial005.py!}
|
||||
```
|
||||
|
||||
### Types with subtypes
|
||||
### Generic types with type parameters
|
||||
|
||||
There are some data structures that can contain other values, like `dict`, `list`, `set` and `tuple`. And the internal values can have their own type too.
|
||||
|
||||
To declare those types and the subtypes, you can use the standard Python module `typing`.
|
||||
To declare those types and the internal types, you can use the standard Python module `typing`.
|
||||
|
||||
It exists specifically to support these type hints.
|
||||
|
||||
#### Lists
|
||||
#### `List`
|
||||
|
||||
For example, let's define a variable to be a `list` of `str`.
|
||||
|
||||
|
|
@ -166,25 +166,30 @@ Declare the variable, with the same colon (`:`) syntax.
|
|||
|
||||
As the type, put the `List`.
|
||||
|
||||
As the list is a type that takes a "subtype", you put the subtype in square brackets:
|
||||
As the list is a type that contains some internal types, you put them in square brackets:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!../../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
Those internal types in the square brackets are called "type parameters".
|
||||
|
||||
In this case, `str` is the type parameter passed to `List`.
|
||||
|
||||
That means: "the variable `items` is a `list`, and each of the items in this list is a `str`".
|
||||
|
||||
By doing that, your editor can provide support even while processing items from the list.
|
||||
|
||||
Without types, that's almost impossible to achieve:
|
||||
By doing that, your editor can provide support even while processing items from the list:
|
||||
|
||||
<img src="/img/python-types/image05.png">
|
||||
|
||||
Without types, that's almost impossible to achieve.
|
||||
|
||||
Notice that the variable `item` is one of the elements in the list `items`.
|
||||
|
||||
And still, the editor knows it is a `str`, and provides support for that.
|
||||
|
||||
#### Tuples and Sets
|
||||
#### `Tuple` and `Set`
|
||||
|
||||
You would do the same to declare `tuple`s and `set`s:
|
||||
|
||||
|
|
@ -197,13 +202,13 @@ This means:
|
|||
* The variable `items_t` is a `tuple` with 3 items, an `int`, another `int`, and a `str`.
|
||||
* The variable `items_s` is a `set`, and each of its items is of type `bytes`.
|
||||
|
||||
#### Dicts
|
||||
#### `Dict`
|
||||
|
||||
To define a `dict`, you pass 2 subtypes, separated by commas.
|
||||
To define a `dict`, you pass 2 type parameters, separated by commas.
|
||||
|
||||
The first subtype is for the keys of the `dict`.
|
||||
The first type parameter is for the keys of the `dict`.
|
||||
|
||||
The second subtype is for the values of the `dict`:
|
||||
The second type parameter is for the values of the `dict`:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial008.py!}
|
||||
|
|
@ -215,6 +220,29 @@ This means:
|
|||
* The keys of this `dict` are of type `str` (let's say, the name of each item).
|
||||
* The values of this `dict` are of type `float` (let's say, the price of each item).
|
||||
|
||||
#### `Optional`
|
||||
|
||||
You can also use `Optional` to declare that a variable has a type, like `str`, but that it is "optional", which means that it could also be `None`:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../../docs_src/python_types/tutorial009.py!}
|
||||
```
|
||||
|
||||
Using `Optional[str]` instead of just `str` will let the editor help you detecting errors where you could be assuming that a value is always a `str`, when it could actually be `None` too.
|
||||
|
||||
#### Generic types
|
||||
|
||||
These types that take type parameters in square brackets, like:
|
||||
|
||||
* `List`
|
||||
* `Tuple`
|
||||
* `Set`
|
||||
* `Dict`
|
||||
* `Optional`
|
||||
* ...and others.
|
||||
|
||||
are called **Generic types** or **Generics**.
|
||||
|
||||
### Classes as types
|
||||
|
||||
You can also declare a class as the type of a variable.
|
||||
|
|
@ -222,13 +250,13 @@ You can also declare a class as the type of a variable.
|
|||
Let's say you have a class `Person`, with a name:
|
||||
|
||||
```Python hl_lines="1 2 3"
|
||||
{!../../../docs_src/python_types/tutorial009.py!}
|
||||
{!../../../docs_src/python_types/tutorial010.py!}
|
||||
```
|
||||
|
||||
Then you can declare a variable to be of type `Person`:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/python_types/tutorial009.py!}
|
||||
{!../../../docs_src/python_types/tutorial010.py!}
|
||||
```
|
||||
|
||||
And then, again, you get all the editor support:
|
||||
|
|
@ -250,7 +278,7 @@ And you get all the editor support with that resulting object.
|
|||
Taken from the official Pydantic docs:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/python_types/tutorial010.py!}
|
||||
{!../../../docs_src/python_types/tutorial011.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
class Person:
|
||||
def __init__(self, name: str):
|
||||
self.name = name
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def get_person_name(one_person: Person):
|
||||
return one_person.name
|
||||
def say_hi(name: Optional[str] = None):
|
||||
if name is not None:
|
||||
print(f"Hey {name}!")
|
||||
else:
|
||||
print("Hello World")
|
||||
|
|
|
|||
|
|
@ -1,23 +1,7 @@
|
|||
from datetime import datetime
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel
|
||||
class Person:
|
||||
def __init__(self, name: str):
|
||||
self.name = name
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
id: int
|
||||
name = "John Doe"
|
||||
signup_ts: datetime = None
|
||||
friends: List[int] = []
|
||||
|
||||
|
||||
external_data = {
|
||||
"id": "123",
|
||||
"signup_ts": "2017-06-01 12:22",
|
||||
"friends": [1, "2", b"3"],
|
||||
}
|
||||
user = User(**external_data)
|
||||
print(user)
|
||||
# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
|
||||
print(user.id)
|
||||
# > 123
|
||||
def get_person_name(one_person: Person):
|
||||
return one_person.name
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
id: int
|
||||
name = "John Doe"
|
||||
signup_ts: Optional[datetime] = None
|
||||
friends: List[int] = []
|
||||
|
||||
|
||||
external_data = {
|
||||
"id": "123",
|
||||
"signup_ts": "2017-06-01 12:22",
|
||||
"friends": [1, "2", b"3"],
|
||||
}
|
||||
user = User(**external_data)
|
||||
print(user)
|
||||
# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
|
||||
print(user.id)
|
||||
# > 123
|
||||
Loading…
Reference in New Issue