在这里插入图片描述

python typing模块

Python的typing模块提供了一种在函数定义中添加类型注解的方式,用于指定函数参数和返回值的类型。这些注解不会在运行时进行类型检查,但可以被静态类型检查工具(如mypy)使用。

效果

为函数添加typing模块的注解后,函数使用者就能清晰的了解函数的参数以及返回值类型,例如:

这是一个没有使用typing函数注解的函数,它的注解都是python自动推导的:

在这里插入图片描述

这是一个使用了python typing模块注解的函数,可以看到,尽管此函数返回值类型复杂,但也能清晰展示:

在这里插入图片描述

常用注解语法

以下是一些常见的函数注解的功能和用法:

1. 基本类型注解:可以使用int、float、str等基本类型来注解函数参数和返回值的类型。

def add(a: int, b: int) -> int:
    return a + b

2. 类型别名注解:可以使用typing模块中的类型别名来注解函数参数和返回值的类型。

from typing import List


def get_length(lst: List[int]) -> int:
    return len(lst)


if __name__ == "__main__":
    my_list = [1, 2, 3, 4, 5]
    print(get_length(my_list))
    my_list = list("hello world")
    print(get_length(my_list))

运行结果:

5
11

3. 可选参数注解:可以使用typing模块中的Optional来注解可选参数的类型。

from typing import Optional

def greet(name: Optional[str] = None) -> str:
    if name:
        return f"Hello, {name}!"
    else:
        return "Hello, world!"

在函数定义中,Optional[str] = None表示参数name的类型可以是str或None。

注意,= None可省略。

以下是示例:

from typing import Optional


def greet1(name: Optional[str] = None) -> str:
    if name:
        return f"Hello, {name}!"
    else:
        return "Hello, world!"


def greet2(name: Optional[str]) -> str:
    if name:
        return f"Hello, {name}!"
    else:
        return "Hello, world!"


if __name__ == "__main__":
    print(greet1())
    print(greet1())
    print(greet1("Arnold"))
    print(greet2("Arnold"))

运行结果:

Hello, world!
Hello, world! 
Hello, Arnold!
Hello, Arnold!

但是上面两个函数看到还不太一样:

在这里插入图片描述

在这里插入图片描述

4. 可变参数注解:可以使用typing模块中的List或Tuple来注解可变参数的类型。

from typing import List


def sum_numbers(*numbers: List[int]) -> int:
    return sum(numbers)


if __name__ == "__main__":
    print(sum_numbers(1,2,3))
    print(sum_numbers(1,2))
 

运行结果:

6
3

5. 泛型注解:可以使用typing模块中的泛型来注解函数参数和返回值的类型。

from typing import List, Tuple


def split_string(s: str) -> Tuple[List[str], List[str]]:
    words = s.split()
    return words, list(reversed(words))


if __name__ == "__main__":
    my_str = "hello world"
    words, re_words = split_string(my_str)
    print(words)
    print(re_words)

运行结果:

['hello', 'world']
['world', 'hello']

6. Callable注解:可以使用typing模块中的Callable来注解函数参数和返回值为可调用对象的类型。

from typing import Callable


def apply_func(func: Callable[[int, int], int], a: int, b: int) -> int:
    return func(a, b)

# 定义一个加法函数


def add(a: int, b: int) -> int:
    return a + b


if __name__ == "__main__":
    # 调用apply_func函数,传入add函数作为参数
    result = apply_func(add, 3, 4)
    print(result)  # 输出:7

看到的注解是这样的:

在这里插入图片描述

7. Union注解:Union用于指定一个变量可以是多个不同类型中的一个。

例如,Union[int, float]表示变量可以是int类型或float类型。

from typing import Union


def square_root(n: Union[int, float]) -> float:
    return n ** 0.5


if __name__ == "__main__":
    print(square_root(2))
    print(square_root(2.44))

运行结果:

2
2.44

8. Dict注解:Dict用于指定一个字典的键和值的类型。

例如,Dict[str, int]表示键是字符串类型,值是整数类型的字典。示例:

from typing import Dict


def count_letters(s: str) -> Dict[str, int]:
    """
    统计字符串中字母出现次数
    """
    letter_count = {}
    for letter in s:
        if letter.isalpha():
            # get(letter, 0)表示如果字典中没有找到字母letter,就返回0
            letter_count[letter] = letter_count.get(letter, 0) + 1
    return letter_count


if __name__ == "__main__":
    print(count_letters("dsf234fdsf"))

运行结果:

{'d': 2, 's': 2, 'f': 3}

在这里插入图片描述

9. Set注解:Set用于指定一个集合的元素类型。

例如,Set[int]表示整数类型的集合。示例:

from typing import Set, List


def get_unique_numbers(numbers: List[int]) -> Set[int]:
    return set(numbers)


if __name__ == "__main__":
    print(get_unique_numbers("dsf234fdsf"))
    print(get_unique_numbers([7, 1, 4, 3, 3, 4, 5 ]))

运行结果:

{'f', '4', 'd', '2', 's', '3'}
{1, 3, 4, 5, 7}

在函数get_unique_numbers中,参数numbers被注解为List[int],表示它应该是一个整数类型的列表。然而,当你调用get_unique_numbers(“dsf234fdsf”)时,你传递给函数的参数是一个字符串,而不是一个整数列表。

在Python中,字符串是可迭代的对象,因此它可以被转换为一个列表。当你使用字符串作为参数调用set()函数时,它会将字符串中的每个字符作为集合的元素。因此,set(“dsf234fdsf”)的结果是一个包含字符串中每个字符的集合:{‘3’, ‘s’, ‘2’, ‘d’, ‘f’, ‘4’}。

注意,python set默认是无序的,元素不会自动进行排序。

20231015补充:类参数类型注解

示例:

class NetInterface:
    '''
    网口类
    '''

    def __init__(self, name: str, is_main: bool):
        self.name = name
        # 是否是主网口(主网口涉及到跟java、mysql同步的逻辑)
        self.is_main = is_main


class InterfaceIpInfo:
    '''
    网口 ip 信息类
    '''

    def __init__(self, net_interface: NetInterface, ip: str, subnet_mask: str, gateway: str):
        self.net_interface = net_interface
        self.ip = ip
        self.subnet_mask = subnet_mask
        self.gateway = gateway


Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐