Python 中 `int* | str*` 和 `int | str` 有什么区别?

新手上路,请多包涵
from typing import Generic, TypeVar, cast
from dataclasses import dataclass

@dataclass
class SteamSave: 
    prop: int


@dataclass
class XboxSave:
    prop: str


T = TypeVar('T', SteamSave, XboxSave)

class Editor(Generic[T]):
    def __init__(self, save: T):
        self.save_data = save

    def print_prop(self):
        print(self.save_data.prop)


class Editor2():
    def __init__(self, save: SteamSave | XboxSave):
        self.save_data = save

    def print_prop(self):
        print(self.save_data.prop)

print(Editor)
print(Editor[SteamSave])
print(Editor[XboxSave])

VSCode 对两个类 self.save_data.prop 的类型推断结果:
图片.png
图片.png

int* | str*int | str 有什么区别,多出来的星号是什么意思?

阅读 1.4k
avatarAI BotBETA

在 Python 的类型注解(type hints)中,并没有直接使用 int* | str* 这样的语法来表示类型。这看起来像是一个误解或者是对其他编程语言(如 C 或 C++)中指针概念的混淆。在 Python 中,int | str 是使用 Python 3.10 及以后版本引入的联合类型(Union Type)的正确方式,它表示一个变量可以是 int 类型或 str 类型中的任何一个。

在你的例子中,Editor 类使用了泛型(Generics)来接受一个类型参数 T,这个 T 被限制为 SteamSaveXboxSave。因此,当你实例化 Editor[SteamSave]Editor[XboxSave] 时,self.save_data 相应地会被推断为 SteamSaveXboxSave 类型的实例,而 self.save_data.prop 则分别被推断为 intstr 类型。

另一方面,Editor2 类直接在其构造函数中使用了 SteamSave | XboxSave 作为 save 参数的类型注解。这同样表示 save 参数可以是 SteamSaveXboxSave 类型的实例。在这种情况下,VSCode 或其他类型检查工具应该能够推断出 self.save_data.prop 的类型也是 intstr(尽管这种推断可能依赖于工具对类属性的理解程度)。

关于 int* | str* 中的星号(*),在 Python 的类型注解中,星号没有直接的含义。如果你在 Python 代码中看到这样的表示,它很可能是个错误,或者是对其他语言特性的误解。在 C 或 C++ 中,星号用于表示指针类型,但在 Python 中,我们不需要(也不能)在类型注解中显式地表示引用或指针。Python 中的变量名总是指向对象的引用,但这种引用是隐式的,不需要在类型注解中显式声明。

总结来说,int | str 是 Python 中表示联合类型的正确方式,而 int* | str* 并不是 Python 中的有效语法,星号(*)在这里没有特殊意义。

3 个回答

int | str表示一个变量可以是int类型或str类型
int* | str*在Python的标准类型注解或类型系统中并不是一个有效的表达式。

python没有 int* | str* 的这种类注。

python的 * 使用场景就是和数组、字典与操作符有关,基本就下面三种:

  • 作为参数使用:

    • def func(*args, **kwargs)

      • *args: 表示arg是一个数组类型的参数
      • **kwargs: 表示kwarg是一个字典类型的参数
# 数组
def add(a, b, c):
    return a + b + c

numbers = [1, 2, 3]
result = add(*numbers)
print(result)  # 输出: 6

# 字典
def print_dict(a, b, c):
    print(f"a: {a}, b: {b}, c: {c}")

dict_values = {'a': 1, 'b': 2, 'c': 3}
print_dict(**dict_values)
  • 作为解构使用
# 数组
In [190]: a = [1, 2, 3]

In [191]: c = [*a, *b]

In [192]: c
Out[192]: [1, 2, 3, '7', '8']

# 字典
In [193]: d = {"a": 1, "b": 22, "c": 333}
In [195]: e = {(1, 2): "tuple of number", ("tom", "jerry"): "Tom and Jerry"}
In [197]: f = {**d, **e}

In [198]: f
Out[198]:
{'a': 1,
 'b': 22,
 'c': 333,
 (1, 2): 'tuple of number',
 ('tom', 'jerry'): 'Tom and Jerry'}
  • 作为运算符

    • 4 * 3 = 12
    • 4 ** 2 = 16
新手上路,请多包涵
  • int* | str* 中的 * 表示选项可以为 None,即可接受这两种类型的变量以及 None 值。例如,变量可以是一个整数、字符串或者是 None。
  • int | str 中没有包含 None,变量必须是 int 类型或 str 类型,禁止为 None。
推荐问题
logo
Microsoft
子站问答
访问
宣传栏