您当前的位置: 首页 >  Python

IT之一小佬

暂无认证

  • 1浏览

    0关注

    1192博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

python代码类型注解

IT之一小佬 发布时间:2022-07-23 10:07:46 ,浏览量:1

注解:

        Python 运行时不强制执行函数和变量类型注解,但这些注解可用于类型检查器、IDE、静态检查器等第三方工具。

        在定义函数时使用“注解”的形式来标注形参和返回值的类型,但这种注解的形式并不会对形参进行任何约束和检查,在实际调用函数时,即使实参不符合形参的类型标注,一样能够正常传递。

Python 中几种基本的变量类型都得到了支持:

a: int = 3
b: float = 3.14
c: str = 'abc'
d: bool = False

下面的函数接收与返回的都是字符串,注解方式如下:

示例代码1:

"""​
    greeting 函数中,参数 name 的类型是 str,返回类型也是 str。子类型也可以当作参数。

​"""


def greeting(name: str) -> str:
    return 'Hello ' + name


a = greeting('dgw')
print(a)

运行结果:

类型别名:

        把类型赋给别名,就可以定义类型别名。本例中,Vector 和 list() 相同,可互换:

示例代码2:

Vector = list()


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


# typechecks; a list of floats qualifies as a Vector.
new_vector = scale(2.0, [1.0, -4.2, 5.4])
print(new_vector)

运行结果:

示例代码3:

from typing import Tuple

# 类型别名  --->给类型赋予一个有意义的名称
Vector2D = Tuple[int, int]  # Vector2D 这个名称清晰的表达了这个对象是一个二维的向量。


def foo(vector: Vector2D):
    print(vector)


foo(vector=(1, 2))
foo((1, 2))

运行结果:

示例代码4:【与类型别名有点类似的,是用 NewType 创建自定义类型,但不同的是 NewType 创建了原始类型的“子类”】

from typing import Tuple
from typing import NewType

# 类型别名  --->给类型赋予一个有意义的名称
Vector2D = Tuple[int, int]  # Vector2D 这个名称清晰的表达了这个对象是一个二维的向量。


def foo(vector: Vector2D):
    print(vector)


# 创建新类型
Vector3D = NewType('Vector3D', Tuple[int, int, int])


def bar(vector: Vector3D):
    print(vector)


# 类型检查成功
# 类型别名和原始类型是等价的
foo(vector=(1, 2))

# 类型检查失败
# NewType创建的是原始类型的“子类”
bar(vector=(1, 2, 3))

# 类型检查成功
# 传入参数必须是 Vector3D 的“实例”
v_3d = Vector3D((4, 5, 6))
bar(vector=v_3d)

运行结果:

 示例代码5:

def demo(name: str = '名字', age: int = 31) -> "str":
    print("函数注解", demo.__annotations__)  # 查看函数注解信息
    print("打印实参", name, age)
    print(type(name), type(age))
    ret = "name:" + name + ', age:' + str(age)
    return ret


a = demo()
print(a)
print('*' * 100)

b = demo('张三')
print(b)
print('*' * 100)

c = demo('张三', 25)
print(c)
print('*' * 100)

print("函数注解", demo.__annotations__)  # 查看函数注解信息

运行结果:

容器类型:

        列表、字典、元组等包含元素的复合类型,用简单的 list,dict,tuple 不能够明确说明内部元素的具体类型。

        因此要用到 typing 模块提供的复合注解功能:

示例代码6:

from typing import List, Dict, Tuple


# 参数1: 元素为 int 的列表
# 参数2: 键为字符串,值为 int 的字典
# 返回值: 包含两个元素的元组
def mix(scores: List[int], ages: Dict[str, int]) -> Tuple[int, int]:
    print(scores)
    print(ages)
    return (0, 0)


a = mix(99, ('zhangsan', 25))
print(a)

运行结果:

如果是 Python 3.9+ 版本,甚至连 typing 模块都不需要了,内置的容器类型就支持了复合注解:

def mix(scores: list[int], ages: dict[str, int]) -> tuple[int, int]:
    return (0, 0)

        在某些情况下,不需要严格区分参数到底是列表还是元组(这种情况还蛮多的)。这时候就可以将它们的特征抽象为更泛化的类型(泛型),比如 Sequence(序列)。

示例代码7:

# Python 3.8 之前的版本
from typing import Sequence as Seq1


def foo(seq: Seq1[str]):
    for item in seq:
        print(item)


foo([1, 2, 3])

# Python 3.9+ 也可以这么写
from collections.abc import Sequence as Seq2


def bar(seq: Seq2[str]):
    for item in seq:
        print(item)


bar([11, 22, 33])

        上述代码中函数的参数不对容器的类型做具体要求,只要它是个序列(比如列表和元组)就可以。

Any:

        如果实在不知道某个类型注解应该怎么写时,这里还有个最后的逃生通道:

示例代码8:

from typing import Any

def foo() -> Any:
    pass

        任何类型都与 Any 兼容。当然如果你把所有的类型都注解为 Any 将毫无意义,因此 Any 应当尽量少使用。

参考链接:typing —— 类型注解支持 — Python 3.10.5 文档

参考文章:Python类型注解,你需要知道的都在这里了 - 知乎 

关注
打赏
1665675218
查看更多评论
立即登录/注册

微信扫码登录

0.0424s