August Rush

一个还在努力成长的小火汁!

游龙当归海,海不迎我自来也。

We create our own demons.

You can reach me at augustrush0923@gmail.com
Python类型标注
发布:2021年02月24日 | 作者:augustrush | 阅读量: 898

Python是一门动态语言,变量和函数的参数不区分类型,好处是方便,灵活。坏处是别人不能直观的看到数据的类型,IDE也不能给出类型提示。

  • python解释器不会因为类型标注而有其他额外的类型校验,检查等。只是方便人看和IDE进行提示,语法检查等工作。也就是说,这些类型注解加不加,对你的代码来说没有任何影响。

  • python3.5之后的版本才支持,3.5版本并不支持。


基本用法

变量名: 类型名指定函数的参数类型,用-> 类型名指定函数的返回值类型

# 变量注解
num: int = 100

# 参数注解
def greeting(name: str) -> str:
    return 'Hello ' + name

class Person:
    def __init__(self):
        self.Name: str = "August Rush"
        self.Age: int = 18


注解类型

原子类型

就是一些built-in的类型,如int, float, complex, bool, str, None, list, tuple, set, dict,不过后面四个作为注解太弱势了,我们只知道变量是什么类型,但是它的元素类型是啥我们无法得知,这时候我们就需要借助typing模块


容器类型


List

List,列表,是list的泛型,基本等同于 list,其后紧跟一个方括号,里面代表了构成这个列表的元素类型

from typing import List
name: List[str] = [3, "亚索", "瑞雯", "菲奥娜"]

另外还可以嵌套声明都是可以的:

lists: List[List[int]] = [[1, 2], [2, 3]]


Tuple

Tuple,元组,是tuple的泛型,其后紧跟一个方括号,方括号中按照顺序声明了构成本元组的元素类型,如 Tuple[X, Y] 代表了构成元组的第一个元素是 X 类型,第二个元素是 Y 类型

from typing import Tuple
info: Tuple[str, int, float] = ("樱木花道", 18, 183.0)

同样地也可以像List一样使用类型嵌套

tuples: Tuple[Tuple[int]] = ((1, 2), (3, 4))


Dict & Mapping

Dict,字典,是dict的泛型;Mapping,映射,是collections.abc.Mapping的泛型。根据官方文档,Dict 推荐用于注解返回类型,Mapping 推荐用于注解参数。它们的使用方法都是一样的,其后跟一个中括号,中括号内分别声明键名、键值的类型

from typing import Dict, Mapping
d: Dict[str, int] = {"1": 1, "2": 2}
m: Mapping[str, int] = {"1": 1, "2": 2}


Set & AbstractSet

Set,集合,是set的泛型;AbstractSet,是collections.abc.Set的泛型。根据官方文档,Set 推荐用于注解返回类型,AbstractSet 用于注解参数。它们的使用方法都是一样的,其后跟一个中括号,里面声明集合中元素的类型

from typing import Set, AbstractSet
num: Set[int] = {1, 2, 3}
flag: AbstractSet[bool] = {True, False}


Sequence

Sequence,是collections.abc.Sequence的泛型,在某些情况下,我们可能并不需要严格区分一个变量或参数到底是列表 list 类型还是元组tuple 类型,我们可以使用一个更为泛化的类型,叫做 Sequence,其用法类似于 List

from typing import Sequence
msgs: Sequence[str] = ["我", "爱", "你"]


其他类型


NoReturn

NoReturn,当一个方法没有返回结果时,为了注解它的返回类型,我们可以将其注解为 NoReturn

from typing import NoReturn
def show() -> NoReturn:
     print("test NoReturn")


Any

Any,是一种特殊的类型,它可以代表所有类型,静态类型检查器的所有类型都与 Any 类型兼容,所有的无参数类型注解和返回类型注解的都会默认使用 Any 类型,也就是说,下面两个方法的声明是完全等价的:

from typing import Any
def add(a):
    return a + 1

def add(a: Any) -> Any:
    return a + 1


Callable

Callable,可调用类型,它通常用来注解一个方法,Callable 在声明的时候需要使用Callable[[Arg1Type, Arg2Type, ...], ReturnType]这样的类型注解,将参数类型和返回值类型都要注解出来

from typing import Callable, NoReturn
def show(msg: str) -> NoReturn:
    print(msg)

def get_msg(msg: str, func: Callable[[str], NoReturn]) -> NoReturn:
    func(msg)


Union

Union,联合类型,Union[X, Y]代表要么是 X 类型,要么是 Y 类型


Optional

Optional,意思是说这个参数可以为空或已经声明的类型,即Optional[X]等价于Union[X, None],注意,只能是一个类型,Optional[X, Y]是错的,但值得注意的是,这个并不等价于可选参数,当它作为参数类型注解的时候,不代表这个参数可以不传递了,而是说这个参数可以传为 None


Generator

如果想代表一个生成器类型,可以使用 Generator,它的声明比较特殊,其后的中括号紧跟着三个参数,分别代表YieldTypeSendTypeReturnType

from typing import Generator
def echo_round() -> Generator[int, float, str]:
    sent = yield 0
    while sent >= 0:
             sent = yield round(sent)
    return 'Done'

当然很多情况下,生成器往往只需要yield内容就够了,我们是不需要 SendType 和 ReturnType 的,可以将其设置为空Generator[int, None, None]


Iterable & Iterator

这个实际上指的就是可迭代类型和迭代器类型,后面中括号内的是迭代的元素的类型

from typing import Iterable, Iterator
def func(a: Iterator[int], b: Iterable[float]):
    print(a, b)


自定义类型


类型别名

直接上示例,其实就是把定义好的类型注解取个名字

from typing import List

Vector = List[float]

def scale(scalar: float, vector: Vector) -> Vector:
     return [scalar * num for num in vector]


TypeVar

TypeVar,我们可以借助它来自定义兼容特定类型的变量,比如有的变量声明为 int、float、None 都是符合要求的,实际就是代表任意的数字或者空内容都可以,其他的类型则不可以,比如列表 list、字典 dict 等等,像这样的情况,我们可以使用 TypeVar 来表示 例如一个人的身高,便可以使用 int 或 float 或 None 来表示,但不能用 dict 来表示,所以可以这么声明:

from typing import TypeVar

height = 1.75
Height = TypeVar('Height', int, float, None)

def get_height() -> Height:
    return height


  • 标签云

  • 支付宝扫码支持一下

  • 微信扫码支持一下



基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建

京ICP备20007446号-1 & 豫公网安备 41100202000460号

网站地图 & RSS | Feed