FastAPI 教程翻译 - Python 类型介绍

FastAPI 教程翻译 - Python 类型介绍

Python Types Intro

Python 3.6+ has support for optional “type hints”.

Python 3.6+ 支持可选的『类型提示』。

These “type hints” are a new syntax (since Python 3.6+) that allow declaring the type of a variable.

这些**『类型提示』**是一种新语法(自 Python 3.6+ 起),允许声明变量的类型。

By declaring types for your variables, editors and tools can give you better support.

通过声明变量的类型,编辑器和工具可以为您提供更好的支持。

This is just a quick tutorial / refresher about Python type hints. It covers only the minimum necessary to use them with FastAPI… which is actually very little.

这只是关于 Python 类型提示的快速教程 / 复习。它仅涵盖将它们与 FastAPI 一起使用所需的最低要求…… 实际上很少。

FastAPI is all based on these type hints, they give it many advantages and benefits.

FastAPI 都是基于这些类型提示的,它们具有许多优点和好处。

But even if you never use FastAPI, you would benefit from learning a bit about them.

但是,即使您从未使用过 FastAPI,您也可以从中学习到一些好处。

Note

注意

If you are a Python expert, and you already know everything about type hints, skip to the next chapter.

如果您是 Python 专家,并且已经了解有关类型提示的所有知识,请跳到下一章。

Motivation

动机

Let’s start with a simple example:

让我们从一个简单的例子开始:

def get_full_name(first_name, last_name):
    full_name = first_name.title() + " " + last_name.title()
    return full_name


print(get_full_name("john", "doe"))

Calling this program outputs:

调用该程序输出:

John Doe

The function does the following:

该函数执行以下操作:

  • Takes a first_name and last_name.

    采用 first_namelast_name

  • Converts the first letter of each one to upper case with title().

    使用 title() 将每个字母的首字母转换为大写。

  • Concatenates them with a space in the middle.

    在中间用空格连接它们。

def get_full_name(first_name, last_name):
    full_name = first_name.title() + " " + last_name.title()
    return full_name


print(get_full_name("john", "doe"))

Edit it

编辑

It’s a very simple program.

这是一个非常简单的程序。

But now imagine that you were writing it from scratch.

但是现在想象一下,您是从头开始编写的。

At some point you would have started the definition of the function, you had the parameters ready…

在某个时候,您将开始定义函数,已经准备好参数……

But then you have to call “that method that converts the first letter to upper case”.

但是然后您必须调用『将第一个字母转换为大写字母的方法』。

Was it upper? Was it uppercase? first_uppercase? capitalize?

upper?是 uppercase?是 first_uppercase?或者是 capitalize

Then, you try with the old programmer’s friend, editor autocompletion.

然后,您尝试使用老程序员的朋友:编辑器自动补全。

You type the first parameter of the function, first_name, then a dot (.) and then hit Ctrl+Space to trigger the completion.

键入函数的第一个参数 first_name,然后输入点(.),然后按 Ctrl+Space 以触发自动补全。

But, sadly, you get nothing useful:

但是,可悲的是,您没有得到任何有用的信息:

在这里插入图片描述

Add types

添加类型

Let’s modify a single line from the previous version.

让我们从以前的版本中修改一行。

We will change exactly this fragment, the parameters of the function, from:

我们将以下位置(函数的参数)的片段:

    first_name, last_name

to:

修改为:

    first_name: str, last_name: str

That’s it.

而已。

Those are the “type hints”:

这些是『类型提示』:

def get_full_name(first_name: str, last_name: str):
    full_name = first_name.title() + " " + last_name.title()
    return full_name


print(get_full_name("john", "doe"))

That is not the same as declaring default values like would be with:

这与声明默认值不同,例如:

    first_name="john", last_name="doe"

It’s a different thing.

这是另一回事。

We are using colons (:), not equals (=).

我们使用冒号(:),而不是等号(=)。

And adding type hints normally doesn’t change what happens from what would happen without them.

添加类型提示通常不会改变没有它们的情况。

But now, imagine you are again in the middle of creating that function, but with type hints.

但是现在,假设您再次处于创建该函数的过程中,但是带有类型提示。

At the same point, you try to trigger the autocomplete with Ctrl+Space and you see:

同时,您尝试使用 Ctrl+Space 触发自动补全,您会看到:

在这里插入图片描述

With that, you can scroll, seeing the options, until you find the one that “rings a bell”:

这样,您可以滚动查看选项,直到找到正确的选项:

在这里插入图片描述

More motivation

更多的动机

Check this function, it already has type hints:

检查此功能,它已经具有类型提示:

def get_name_with_age(name: str, age: int):
    name_with_age = name + " is this old: " + age
    return name_with_age

Because the editor knows the types of the variables, you don’t only get completion, you also get error checks:

因为编辑器直到变量的类型,所以您不仅可以完成操作,还可以进行错误检查:

在这里插入图片描述

Now you know that you have to fix it, convert age to a string with str(age):

现在您知道必须修复它,将 age 转换为带有 str(age) 的字符串:

def get_name_with_age(name: str, age: int):
    name_with_age = name + " is this old: " + str(age)
    return name_with_age

Declaring types

声明类型

You just saw the main place to declare type hints. As function parameters.

您刚刚看到了声明类型提示的主要地方。作为功能参数。

This is also the main place you would use them with FastAPI.

这也是将它们与 FastAPI 一起使用的主要位置。

Simple types

简单类型

You can declare all the standard Python types, not only str.

您可以声明所有标准的 Python 类型,而不仅是 str

You can use, for example:

您可以使用,例如:

  • int
  • float
  • bool
  • bytes
def get_items(item_a: str, item_b: int, item_c: float, item_d: bool, item_e: bytes):
    return item_a, item_b, item_c, item_d, item_d, item_e

Types with subtypes

具有子类型的类型

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.

有些数据结构可以包含其他值,例如 dictlistsettuple。内部值也可以具有自己的类型。

To declare those types and the subtypes, you can use the standard Python module typing.

要声明这些类型和子类型,可以使用标准的 Python 模块 typing

It exists specifically to support these type hints.

它专门存在以支持这些类型提示。

Lists
列表

For example, let’s define a variable to be a list of str.

例如,让我们将变量定义为 strlist

From typing, import List (with a capital L):

typing 中,导入 List(首字母大写的 L):

from typing import List


def process_items(items: List[str]):
    for item in items:
        print(item)

Declare the variable, with the same colon (:) syntax.

用相同的冒号(:)语法声明变量。

As the type, put the List.

作为类型,输入 List

As the list is a type that takes a “subtype”, you put the subtype in square brackets:

由于列表是带有『子类型』的类型,因此请将子类型放在方括号中:

from typing import List


def process_items(items: List[str]):
    for item in items:
        print(item)

That means: "the variable items is a list, and each of the items in this list is a str".

这意味着:『变量 items 是一个 list,并且该列表中的每个元素都是 str』。

By doing that, your editor can provide support even while processing items from the list.

这样,即使在处理列表中的项目时,您的编辑器也可以提供支持。

Without types, that’s almost impossible to achieve:

几乎没有什么类型是不可以实现的:

在这里插入图片描述

Notice that the variable item is one of the elements in the list items.

注意,变量 item 是列表 items 中的一个元素。

And still, the editor knows it is a str, and provides support for that.

而且,编辑器仍然知道它是一个 str,并且为此提供了支持。

Tuples and Sets
元组和集合

You would do the same to declare tuples and sets:

声明 tuples 和 sets 的方法相同:

from typing import Set, Tuple


def process_items(items_t: Tuple[int], items_s: Set[bytes]):
    return items_t, items_s

This means:

这表示:

  • The variable items_t is a tuple, and each of its items is an int.

    变量 items_t 是一个 tuple,其每个元素都是一个 int

  • The variable items_s is a set, and each of its items is of type bytes.

    变量 items_s 是一个 set,其每个元素的类型都是 bytes

Dicts
字典

To define a dict, you pass 2 subtypes, separated by commas.

要定义 dict,您可以传递 2 个子类型,以逗号分隔。

The first subtype is for the keys of the dict.

第一个子类型用于 dict 的键。

The second subtype is for the values of the dict:

第二个子类型用于 dict 的值。

from typing import Dict


def process_items(prices: Dict[str, float]):
    for item_name, item_price in prices.items():
        print(item_name)
        print(item_price)

This means:

这表示:

  • The variable prices is a dict:

    这个变量 prices 是一个 dict

    • The keys of this dict are of type str (let’s say, the name of each item).

      dict 的键的类型是 str(假设每个商品的名称)。

  • The values of this dict are of type float (let’s say, the price of each item).

    dict 的值的类型是 float(假设每个商品的价格)。

Classes as types

类作为类型

You can also declare a class as the type of a variable.

您也可以将类声明为变量的类型。

Let’s say you have a class Person, with a name:

假设您有一个名为 Person 的类,其名称为:

class Person:
    def __init__(self, name: str):
        self.name = name


def get_person_name(one_person: Person):
    return one_person.name

Then you can declare a variable to be of type Person:

然后,您可以将变量声明为 Person 类型:

class Person:
    def __init__(self, name: str):
        self.name = name


def get_person_name(one_person: Person):
    return one_person.name

And then, again, you get all the editor support:

然后,再次获得所有编辑器支持:

在这里插入图片描述

Pydantic models

Pydantic 模型

Pydantic is a Python library to perform data validation.

Pydantic 是用于执行数据验证的 Python 库。

You declare the “shape” of the data as classes with attributes.

您将数据的『形状』声明为具有属性的类。

And each attribute has a type.

每个属性都有一个类型。

Then you create an instance of that class with some values and it will validate the values, convert them to the appropriate type (if that’s the case) and give you an object with all the data.

然后,创建带有某些值的该类的实例,它将验证这些值,将它们转换为适当的类型(如果是这种情况),并为您提供一个包含所有数据的对象。

And you get all the editor support with that resulting object.

然后,您将得到该对象的所有编辑器支持。

Taken from the official Pydantic docs:

取自 Pydantic 官方文档:

from datetime import datetime
from typing import List

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

Info

信息

To learn more about Pydantic, check its docs.

要了解有关 Pydantic 的更多信息,请查看其文档

FastAPI is all based on Pydantic.

FastAPI 全部基于 Pydantic。

You will see a lot more of all this in practice in the Tutorial - User Guide.

教程 - 用户指南 中,您将在实践中看到更多的相关信息。

Type hints in FastAPI

FastAPI 中的类型提示

FastAPI takes advantage of these type hints to do several things.

FastAPI 利用这些类型提示来做几件事。

With FastAPI you declare parameters with type hints and you get:

使用 FastAPI,您可以使用类型提示来声明参数,并得到:

  • Editor support.

    编辑器支持

  • Type checks.

    类型检查

…and FastAPI uses the same declarations to:

…… 和 FastAPI 使用相同的声明来:

  • Define requirements: from request path parameters, query parameters, headers, bodies, dependencies, etc.

    定义要求:来自请求的路径参数、查询参数、headers、请求体、依赖项等等。

  • Convert data: from the request to the required type.

    转换数据:从请求到所需的类型。

  • Validate data: coming from each request:

    验证数据:来自每个请求:

  • Generating automatic errors returned to the client when the data is invalid.

    当数据无效时,自动生成错误返回给客户端。

  • Document the API using OpenAPI:

    使用 OpenAPI 的 API 文档:

    • which is then used by the automatic interactive documentation user interfaces.

      然后由自动交互式文档用户界面使用。

This might all sound abstract. Don’t worry. You’ll see all this in action in the Tutorial - User Guide.

这听起来可能很抽象。不用担心您将在 教程 - 用户指南 中看到所有这些操作。

The important thing is that by using standard Python types, in a single place (instead of adding more classes, decorators, etc), FastAPI will do a lot of the work for you.

重要的是,通过使用标准的 Python 类型,在一个地方(而不是添加更多的类、装饰器等等),FastAPI 将为您完成很多工作。

Info

信息

If you already went through all the tutorial and came back to see more about types, a good resource is the “cheat sheet” from mypy.

ngolo.com/tutorial/).

这听起来可能很抽象。不用担心您将在 教程 - 用户指南 中看到所有这些操作。

The important thing is that by using standard Python types, in a single place (instead of adding more classes, decorators, etc), FastAPI will do a lot of the work for you.

重要的是,通过使用标准的 Python 类型,在一个地方(而不是添加更多的类、装饰器等等),FastAPI 将为您完成很多工作。

Info

信息

If you already went through all the tutorial and came back to see more about types, a good resource is the “cheat sheet” from mypy.

如果您已经遍历了所有教程,然后又回来查看有关类型的更多信息,那么不错的资源是 the “cheat sheet” from mypy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值