为什么在 Python 生产代码中使用元组可能不受欢迎

作者:微信公众号:【架构师老卢】
11-21 8:45
10

元组功能多样且实用,但在生产代码中我却不怎么常见到它们。以下是一些原因:

为元组编写类型提示可能不够清晰明确 假设我们有一个执行某些操作并返回元组的函数。

def do_stuff() -> tuple[str, int, int]:
    """
    一些文档字符串
    """
    fruit_name: str = get_fruit_name()
    price: int = get_price()
    quantity: int = get_quantity()

    return fruit_name, price, quantity

^注意,当我们尝试编写类型提示时,我们使用了 tuple[str, int, int]

这仅仅意味着我们的函数旨在返回一个长度为3的元组——第一个元素是字符串,另外两个是整数。

这不是很简单明了吗?

这样做存在的问题 乍一看,我们知道返回的是 tuple[str, int, int],但乍一看,我们并不知道这个 tuple[str, int, int] 应该表示什么。 我们需要阅读代码才能推断出它表示的是 (fruit_name, price, quantity)。 在大型代码库中,由于代码众多,要推断这类内容可能会花费相当长的时间。

我的同事们(我也认同)似乎更倾向的做法 typing.NamedTuple

命名元组就是一种我们可以通过两种方式访问的元组。我们可以像普通元组那样通过索引来访问它:

from typing import NamedTuple

class FruitInfo(NamedTuple):
    fruit: str
    price: int
    quantity: int

info = FruitInfo(fruit="apple", price=5, quantity=100)

print(info)         # FruitInfo(fruit='apple', price=5, quantity=100)
print(info[0])      # apple
print(info[1])      # 5
print(info[2])      # 100

或者我们可以像访问对象那样来访问它。

from typing import NamedTuple

class FruitInfo(NamedTuple):
    fruit: str
    price: int
    quantity: int

info = FruitInfo(fruit="apple", price=5, quantity=100)

print(info)         # FruitInfo(fruit='apple', price=5, quantity=100)
print(info.fruit)       # apple
print(info.price)       # 5
print(info.quantity)    # 100

我们更倾向于像访问对象的属性那样来访问这些值。

这主要是因为这样做能让我们的代码更加清晰明确。

在类型提示中使用命名元组 使用元组时

def do_stuff() -> tuple[str, int, int]:
    """
    一些文档字符串
    """
    fruit: str = get_fruit_name()
    price: int = get_price()
    quantity: int = get_quantity()

    return fruit, price, quantity

使用命名元组时

from typing import NamedTuple

class FruitInfo(NamedTuple):
    fruit: str
    price: int
    quantity: int

def do_stuff() -> FruitInfo:
    """
    一些文档字符串
    """
    fruit: str = get_fruit_name()
    price: int = get_price()
    quantity: int = get_quotity()

    return FruitInfo(
        fruit=fruit, 
        price=price, 
        quantity=quantity
    )

从可读性角度看命名元组的优势 乍一看,我们就能确定返回的是 FruitInfo。 乍一看,我们就知道 FruitInfo 包含3个属性——fruitpricequantity。 乍一看,我们还知道 fruit 应该是一个字符串,而 pricequantity 应该是整数。 而且我们仍然可以像对待普通元组那样对待命名元组。

info = FruitInfo(fruit="apple", price=5, quantity=100)

f, p, q = info

print(f, p, q)  # apple 5 100

** 定义一个命名元组可能要多写几行代码,但它能让我们的代码可读性更强、更加清晰。

相关留言评论
昵称:
邮箱: