]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
📝 Add docs in Python Types for Optional (#1377)
authoryaegassy <yaegassy@users.noreply.github.com>
Fri, 12 Jun 2020 21:44:23 +0000 (06:44 +0900)
committerGitHub <noreply@github.com>
Fri, 12 Jun 2020 21:44:23 +0000 (23:44 +0200)
* 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>
docs/en/docs/python-types.md
docs_src/python_types/tutorial009.py
docs_src/python_types/tutorial010.py
docs_src/python_types/tutorial011.py [new file with mode: 0644]

index 46420362c8de43611b4099147d69b82a941ff654..b0dd05468579ed1c7470afa2267f929f8aa3da0f 100644 (file)
@@ -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!}
 ```
 
-That means: "the variable `items` is a `list`, and each of the items in this list is a `str`".
+!!! tip
+    Those internal types in the square brackets are called "type parameters".
+
+    In this case, `str` is the type parameter passed to `List`.
 
-By doing that, your editor can provide support even while processing items from the list.
+That means: "the variable `items` is a `list`, and each of the items in this list is a `str`".
 
-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
index 468cffc2dcfe0f59758b43219b61c881ae80312a..6328a1495c858d34e66c35b587d48ea2df983614 100644 (file)
@@ -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")
index faeb02a58d74c198c2d53fffbf2fbfcc20c23b02..468cffc2dcfe0f59758b43219b61c881ae80312a 100644 (file)
@@ -1,23 +1,7 @@
-from datetime import datetime
-from typing import List
+class Person:
+    def __init__(self, name: str):
+        self.name = name
 
-from pydantic import BaseModel
 
-
-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
diff --git a/docs_src/python_types/tutorial011.py b/docs_src/python_types/tutorial011.py
new file mode 100644 (file)
index 0000000..047b633
--- /dev/null
@@ -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