将一个类型定义为常量的联合类型

编程语言 2026-07-08

我有一个Python函数,它接受一个 socket.AddressFamily 参数。

import socket

def fn(family: socket.AddressFamily) -> None:
    ...

这段代码工作正常。然而,intersphinx不知道这个类型,因为它没有被文档化。

实际上这个函数接受三种该类型的具体实例:socket.AF_INETsocket.AF_INET6socket.AF_UNSPEC。我不知道该如何为这个类型写出注解。我尝试了类似下面这样的写法:

import socket
from typing import Literal

def fn(family: Literal[socket.AF_INET, socket.AF_INET6, socket.AF_UNSPEC]) -> None:
    ...

现在,运行mypy的结果是:

$ mypy test.py 
test.py:5: error: Parameter 1 of Literal[...] is invalid  [valid-type]
Found 1 error in 1 file (checked 1 source file)

我可以把传给这个函数的类型限制为这几个具体的值吗?

解决方案

关于 Literal 的官方定义如下:官方定义

在运行时,作为 Literal[...] 的类型参数可以允许任意值,但类型检查器可能会施加限制。

对于 mypy特别地(原文中的强调):

字面量类型可以包含一个或多个字面布尔值、整数、字符串、字节以及枚举值。然而,字面量类型 不能 包含任意表达式......

因此在这种情况下,你需要使用底层的整数:

def fn(family: Literal[2, 10, 0]) -> None:

或者,更符合我的偏好,使用枚举值:

def fn(family: Literal[socket.AddressFamily.AF_INET, socket.AddressFamily.AF_INET6, socket.AddressFamily.AF_UNSPEC]) -> None:

Mypy Playground

其他类型检查器可能会有所不同(例如 [ty] 允许 Literal[socket.AF_INET, ...] 以及上述两种形式)。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章