CPython struct 模块完全指南:用格式字符串在 Python 值与二进制字节间互转
struct 是 CPython 标准库中专门用于"把 Python 值打包成字节、再把字节解包成 Python 值"的模块。它在两个典型场景中不可替代:一是与外部数据源(文件、网络连接)按约定的二进制布局交换数据;二是在 Python 应用与 C 层之间按 C 结构体内存布局传输数据。读完本文你将掌握格式字符串的全部类型码与字节序控制字符、七个模块级函数与 Struct 类的完整用法,并理解其背后的 C 实现机制,能够直接写出跨平台、可复用的二进制序列化代码。
struct 模块的核心设计理念非常简单:用一串紧凑的**格式字符串(format string)**描述"数据长什么样",CPython 据此自动完成 Python 值与字节之间的转换。官方参考文档位于 Doc/library/struct.rst,纯 Python 的公共接口与文档字符串定义在 Lib/struct.py,而真正的实现是一个用 C 写的高性能加速模块 _struct,源码见 Modules/_struct.c。
模块定位与两种使用模式
从 Lib/struct.py 可以看到,struct 本身只是一个"转发层":它把 calcsize、pack、pack_into、unpack、unpack_from、iter_unpack、Struct 和 error 等名字全部从底层的 _struct 加速模块再导出:
from _struct import *
from _struct import _clearcache # noqa: F401
from _struct import __doc__ # noqa: F401
_struct 的 C 实现(Modules/_struct.c)把格式字符串的编译、内存读写等热点逻辑全部下沉到 C 层,因此性能远优于纯 Python 逐字段手工拼装字节的做法。
在 Modules/_struct.c 中可以看到它的核心数据结构:formatdef 结构体以"表驱动"方式为每一种格式字符登记了 size(字节宽)、alignment(对齐要求)以及一对 unpack/pack 函数指针;formatcode 则在编译格式字符串后记录每个字段的偏移量、尺寸和重复次数:
typedef struct _formatdef {
const char *format;
Py_ssize_t size;
Py_ssize_t alignment;
PyObject* (*unpack)(_structmodulestate *, const char *,
const struct _formatdef *);
int (*pack)(_structmodulestate *, char *, PyObject *,
const struct _formatdef *);
} formatdef;
typedef struct _formatcode {
const struct _formatdef *fmtdef;
Py_ssize_t offset;
Py_ssize_t size;
Py_ssize_t repeat;
} formatcode;
正是这样的设计,让"格式字符"与"具体机器的 C 类型大小/对齐"可以在运行时查表绑定,实现后续要讲的 native 与 standard 两种模式。
函数与异常
struct 模块定义了一个异常和六个模块级函数。所有接收 buffer 参数的函数,都要求参数对象实现缓冲区协议,并提供可读或可读写缓冲区;最常见的类型是 bytes 与 bytearray,但任何能被看作字节数组、实现缓冲区协议的对象(如 memoryview、array.array)都能直接使用,从而避免额外的拷贝。
异常 error
在对各种场合(如格式错误、整数越界、缓冲区长度不足)抛出;异常的实参是一段描述错误的字符串。
>>> import struct
>>> struct.pack('>h', 99999)
Traceback (most recent call last):
...
struct.error: 'h' format requires -32768 <= number <= 32767
这条错误消息并非随手写死,而是由 C 实现中的 _range_error() 根据该字段的字节宽度动态计算的(见 Modules/_struct.c):对有符号整数,错误范围是 min ~ max;对无符号整数则是 0 <= number <= max。
pack(format, v1, v2, ...)
返回一个 bytes 对象,其中依次存放按 format 打包后的 v1、v2……参数的数量与取值必须和格式字符串的要求精确匹配,否则抛 struct.error。
>>> struct.pack('>bhl', 1, 2, 3)
b'\x01\x00\x02\x00\x00\x00\x03'
pack_into(format, buffer, offset, v1, v2, ...)
把打包结果写入可写缓冲区 buffer 的 offset 位置,而不是新建 bytes。注意 offset 是必填参数;它可以是负数,此时从缓冲区末尾向前计数。
>>> import array
>>> buf = array.array('b', [0] * 10) # 一个可写缓冲对象
>>> struct.pack_into('<I', buf, 0, 0x12345678)
>>> struct.unpack_from('<I', buf, 0)
(305419896,)
unpack(format, buffer)
按 format 从 buffer 解包(通常与 pack(format, ...) 配对使用),返回值是元组——即使只包含一个元素也是如此。缓冲区的字节数必须恰好等于格式所需大小(即 calcsize(format) 的值)。
unpack_from(format, /, buffer, offset=0)
从 buffer 的 offset 位置开始解包;offset 默认是 0,可为负(从缓冲区末尾计数)。要求缓冲区在 offset 之后的剩余字节数至少为格式所需大小。解包得到的结果同样是元组。
unpack_from 在解析"前置了长度或魔数、后面紧跟多个定长记录"的报文时尤其好用,因为它允许只解包缓冲区中从指定偏移开始的子区,无需先切片。
iter_unpack(format, buffer)
返回一个迭代器,反复从 buffer 中读取等长的块并解包,直到耗尽全部内容。缓冲区的字节数必须是 calcsize(format) 的整数倍。每次迭代产生一个元组。
>>> struct.iter_unpack('>H', b'\x00\x01\x00\x02\x00\x03')
<iterator object at 0x...>
>>> list(struct.iter_unpack('>H', b'\x00\x01\x00\x02\x00\x03'))
[(1,), (2,), (3,)]
在 C 实现中,iter_unpack 由一个专用的迭代器类型 unpackiter_type 支撑(见 Modules/_struct.c),它实现了 __length_hint__ 以便让 list() 等消费方预分配容量,随后每次 __next__ 前进一个"格式大小"的步长。
该函数在 Python 3.4 中加入。
calcsize(format)
返回格式 format 对应的结构大小(也就是 pack(format, ...) 产出的 bytes 的字节数)。
>>> struct.calcsize('>bhl')
7
格式字符串
格式字符串描述了打包/解包时的数据布局,由**可选的前缀字符 + 一个或多个格式字符(类型码)**构成:
- 前缀字符:控制整条数据的字节序、尺寸与对齐;
- 格式字符:描述具体每个数据值的类型与宽度(见下文类型码表)。
字节序、尺寸与对齐
默认情况下(不写前缀或前缀为 @),C 类型按机器原生格式与原生字节序表示,并按 C 编译器规则插入必要的填充字节以对齐。选择这一默认行为是为了让打包结果与对应 C 结构体的内存布局完全一致。
前缀字符的可选值如下表:
| 字符 | 字节序 | 尺寸 | 对齐 |
|---|---|---|---|
@ |
native(原生) | native(原生) | native(原生) |
= |
native(原生) | standard(标准) | none(无) |
< |
little-endian(小端) | standard(标准) | none(无) |
> |
big-endian(大端) | standard(标准) | none(无) |
! |
network(网络序,即大端) | standard(标准) | none(无) |
若第一个字符不是上述任一前缀,则默认视为 @。
关于字节序的直观例子:数字 1023(十六进制 0x3ff)的两种字节表示分别是——大端(>)下为 03 ff,小端(<)下为 ff 03:
>>> import struct
>>> struct.pack('>h', 1023)
b'\x03\xff'
>>> struct.pack('<h', 1023)
b'\xff\x03'
原生字节序由宿主机决定:Intel x86、AMD64(x86-64)和 Apple M1 都是小端;IBM z 系列及许多老架构是大端。可以用 sys.byteorder 查看当前系统字节序:
>>> import sys
>>> sys.byteorder
'little'
尺寸与对齐的取值来源不同:
- native 尺寸与对齐由 C 编译器的
sizeof表达式确定(_struct的 native 表中直接使用sizeof(short)、_Alignof(int)、sizeof(void *)等编译期常量,见 Modules/_struct.c),并且始终与原生字节序绑定; - standard 尺寸只取决于类型码本身(见下节类型码表中"Standard size"列)。
@ 与 = 的差异要特别注意:两者都使用原生字节序,但 = 的尺寸与对齐是标准化的(即各类型码取标准宽度、不做任何对齐填充)。
! 即网络字节序,按 IETF RFC 1700 的定义恒为大端。
模块没有提供"强制非原生字节序(强制字节交换)"的通用开关——需要非原生字节序时,请根据目标平台明确选用 < 或 >。
对齐规则的三条要点:
- 填充字节只在相邻结构成员之间自动加入;编码后结构的开头与末尾不会自动加填充;
- 使用非原生尺寸/对齐的前缀(
<、>、=、!)时,不会插入任何填充; - 若希望结构末尾也按某种类型的对齐要求补齐,可以在格式串末尾写上该类型码并附加重复次数 0(例如
'llh0l'),详见下文示例。
类型码全表
类型码描述单个值的 C 类型与 Python 类型映射。"Standard size"列给出的是使用标准尺寸(即格式串以 <、>、! 或 = 开头)时该值占用的字节数;使用 native 尺寸时,大小取决于平台。
| 格式 | C 类型 | Python 类型 | 标准尺寸 | 备注 |
|---|---|---|---|---|
x |
pad byte(填充字节) | 无对应值 | — | (7) |
c |
char |
长度 1 的 bytes | 1 | |
b |
signed char |
int | 1 | (2) |
B |
unsigned char |
int | 1 | (2) |
? |
_Bool |
bool | 1 | (1) |
h |
short |
int | 2 | (2) |
H |
unsigned short |
int | 2 | (2) |
i |
int |
int | 4 | (2) |
I |
unsigned int |
int | 4 | (2) |
l |
long |
int | 4 | (2) |
L |
unsigned long |
int | 4 | (2) |
q |
long long |
int | 8 | (2) |
Q |
unsigned long long |
int | 8 | (2) |
n |
ssize_t |
int | — | (2)(3) |
N |
size_t |
int | — | (2)(3) |
e |
_Float16 |
float | 2 | (4)(6) |
f |
float |
float | 4 | (4) |
d |
double |
float | 8 | (4) |
Zf |
float complex |
complex | 8 | (10) |
Zd |
double complex |
complex | 16 | (10) |
s |
char[] |
bytes | — | (9) |
p |
char[] |
bytes | — | (8) |
P |
void * |
int | — | (2)(5) |
版本相关说明:
- Python 3.3 起支持
n与N格式; - Python 3.6 起支持
e格式; - Python 3.14 起曾加入
F与D格式; - Python 3.15 起支持
Zf与Zd格式; - Python 3.16 起
F与D格式被标记为弃用(新代码应改用Zf/Zd)。从 Modules/_struct.c 的 native 表可见,F/D与Zf/Zd指向完全相同的 pack/unpack 函数,仅是兼容别名。
表注逐条详解:
- (1)
?与_Bool:?对应 C99 起定义的_Bool类型;在标准模式下占 1 字节。 - (2) 整数格式与
__index__:对任何整数格式码,若传入的不是整数但带有__index__方法,则会先调用该方法把参数转成整数再打包(Python 3.2 起)。在 C 层,这一逻辑位于get_pylong():先判断PyLong_Check,失败后再检查PyIndex_Check并调用索引协议(见 Modules/_struct.c)。这意味着numpy整数、实现了__index__的自定义类型等都可以直接打包。 - (3)
n/N仅限 native:n(ssize_t)与N(size_t)只在 native 尺寸下可用(默认模式或显式@);标准尺寸下请按需选用其他整数格式。 - (4) 浮点用 IEEE 754:
f、d、e打包出的表示无论平台自身的浮点格式如何,都分别采用 IEEE 754 binary32、binary64、binary16。 - (5)
P仅限 native:P(void *指针宽度)只在 native 字节序下可用(默认或@)。=前缀虽然按宿主机选择端序,但_struct并不把=视为 native 顺序,因此P不可与=联用。 - (6)
e半精度浮点:对应 2008 版 IEEE 754 标准引入的 binary16 "half precision"。它含 1 位符号、5 位指数和 11 位有效精度(显式存储 10 位),全精度下可表示约6.1e-05到6.5e+04之间的数。该类型在 C 编译器中支持不普遍(需编译器支持 C23 附录 H 的_Float16);在典型机器上可用unsigned short存储,但不能直接参与数学运算。C 层对它的打包本质上也是按 2 字节宽度读写(见 Modules/_struct.c 中e与h/H同为sizeof(short))。 - (7)
x填充:打包时x插入一个 NUL 字节。 - (8)
pPascal 字符串:在固定字节数(由 count 给出)内编码"短变长字符串":第 1 字节存字符串长度(与 255 取较小者),随后是字符串内容。若传入的字节串超过count-1字节,只保留前count-1字节;若短于count-1,则用 NUL 补足到恰好 count 字节。解包时p会消费 count 字节,但返回的 bytes 对象永远不会超过 255 字节。打包时接受bytes与bytearray参数。 - (9)
s与c的区别:s的 count 表示字节串长度而非重复次数。'10s'表示单个 10 字节字符串 ↔ 单个 Python 字节串;而'10c'表示 10 个各自独立的单字节字符 ↔ 10 个独立的 bytes 对象(等价写法cccccccccc)。count 缺省为 1。打包时字节串会被截断或用 NUL 补齐到指定长度;解包时得到的 bytes 恒为指定字节数。特例:'0s'表示单个空字节串,而'0c'表示 0 个字符。打包时同样接受bytes/bytearray。 - (10)
Zf/Zd复数:两个分量(实部、虚部)分别用 IEEE 754 binary32/binary64 表示,不受平台浮点格式影响。需要注意:尽管复数在 C 语言中属于可选特性,但这里无条件可用。按 C11 标准,每个 complex 类型由一个二元 C 数组表示,分别存放实部与虚部。F/D仅作为Zf/Zd的兼容别名保留。
重复计数、空白与范围检查
类型码前可以加整数重复次数,例如 '4h' 与 'hhhh' 完全等价。
格式字符串之间的空白字符会被忽略,但 count 与其所属格式码之间不能有空白(否则 4 h 会被解析成独立的 4 与 h 两个字段,通常导致错误)。
打包时若用整数格式(b B h H i I l L q Q)传入的值超出该格式的合法范围,会抛 struct.error(Python 3.1 之前部分整数格式是回绕并抛 DeprecationWarning,此后一律改为抛错,因此越界不会再静默产生错误的二进制数据)。
? 类型的返回值恒为 True 或 False;打包时使用参数的真值;原生或标准 bool 表示中的 0/1 会被正确打包,解包时任何非零字节都视为 True。
官方示例精读
下面的示例全部来自官方文档,可直接在交互式环境中运行验证。注意:native 字节序示例(@ 前缀或无前缀)的输出取决于平台与编译器,可能与读者本机的输出不同。
用大端序打包并解包三种不同宽度的整数:
>>> from struct import *
>>> pack(">bhl", 1, 2, 3)
b'\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('>bhl', b'\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> calcsize('>bhl')
7
尝试打包超出字段范围的整数:
>>> pack(">h", 99999)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
struct.error: 'h' format requires -32768 <= number <= 32767
s 与 c 的区别演示:
>>> pack("@ccc", b'1', b'2', b'3')
b'123'
>>> pack("@3s", b'123')
b'123'
解包结果赋名 / 包装成命名元组——实际解析网络二进制记录时的标准手法:
>>> record = b'raymond \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)
>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name=b'raymond ', serialnum=4658, school=264, gradelevel=8)
native 模式下类型码顺序影响结构大小(因为隐式填充,编译出的格式可能比字段"内容"更长);而标准模式完全由用户负责填充。下面这个例子在小端机器上运行,注意第一个 pack 在打包 '#' 之后自动补了 3 个 NUL 字节,把后续整数对齐到 4 字节边界:
>>> pack('@ci', b'#', 0x12131415)
b'#\x00\x00\x00\x15\x14\x13\x12'
>>> pack('@ic', 0x12131415, b'#')
b'\x15\x14\x13\x12#'
>>> calcsize('@ci')
8
>>> calcsize('@ic')
5
用末尾零重复计数对齐结构尾:假设平台 long 按 4 字节对齐,格式 'llh0l' 会在末尾补 2 个填充字节:
>>> pack('@llh0l', 1, 2, 3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x03\x00\x00'
两大应用场景:native 格式与 standard 格式
struct 的两个主要应用领域会构建风格迥异的格式字符串:
- Python 与 C 代码(同一编译器构建的应用)之间的数据交换——使用 native 格式;
- 遵循约定布局的跨应用/跨机器数据交换——使用 standard 格式。
native 格式(原生格式)
当格式串要复刻本机 native 布局时,字节序与填充由编译器与机器架构决定。此时应使用 @ 前缀指明原生字节序与数据尺寸;内部填充字节通常由模块自动插入。为了让连续多个 chunk 正确对齐到字节边界,常常需要在格式串末尾使用一个零重复计数类型码来"凑整"。
在 64 位小端机器上:
>>> calcsize('@lhl')
24
>>> calcsize('@llh')
18
第二个格式串 @llh 在结构末尾没有被补齐到 8 字节边界(18 = 8 + 8 + 2,少了尾部对齐)。用零重复格式码解决:
>>> calcsize('@llh0l')
24
x 类型码也可以承担类似职责,但对 native 格式,更推荐零重复格式(如 '0l'),因为它能把末尾对齐与"此处无字段"的语义区分得更干净。模块默认就使用 native 字节序与对齐,但官方建议显式写出 @ 前缀,让意图一目了然。
standard 格式(标准格式)
当数据要越过当前进程边界(网络传输、落盘存储等)时,必须显式指定字节序、尺寸与对齐,绝不能假定对端与本地机器一致。例如:网络字节序是大端,而主流 CPU 多为小端。一旦布局被显式约定,代码就不再依赖运行平台的具体特性。
标准格式串的首字符一般用 < 或 >(或 !);填充完全由程序员负责。此时零重复格式码不再起作用,需要补位时必须在需要处显式书写 x 填充字节。沿用上一节的例子:
>>> calcsize('<qh6xq')
24
>>> pack('<qh6xq', 1, 2, 3) == pack('@lhl', 1, 2, 3)
True
>>> calcsize('@llh')
18
>>> pack('@llh', 1, 2, 3) == pack('<qqh', 1, 2, 3)
True
>>> calcsize('<qqh6x')
24
>>> calcsize('@llh0l')
24
>>> pack('@llh0l', 1, 2, 3) == pack('<qqh6x', 1, 2, 3)
True
同样注意:以上结果在 64 位机器上成立,在不同机器上并不保证一致。例如在 32 位机器上,long 是 4 字节,结果完全不同:
>>> calcsize('<qqh6x')
24
>>> calcsize('@llh0l')
12
>>> pack('@llh0l', 1, 2, 3) == pack('<qqh6x', 1, 2, 3)
False
这组对照实验也直观说明了一条工程原则:跨进程/跨机器传输务必使用 standard 格式并自管填充。
Struct 类:编译一次,反复使用
class struct.Struct(format)
返回一个按照格式串 format 读写二进制数据的 Struct 对象。相比每次调用模块级函数,先创建一次 Struct 对象再反复调用其方法更高效,因为格式串只被编译一次。
不过在多数场景下二者差异不大:传给模块级函数的最近使用的若干格式串的编译结果会被缓存,因此程序里格式串种类不多时无需特意复用 Struct 实例。这一缓存正是 _struct 模块状态里的 cache 字典(见 Modules/_struct.c),模块级函数通过 cache_struct_converter 从缓存中取编译对象、未命中才新建,Lib/struct.py 中再导出的 _clearcache() 则用于清空该缓存。
Struct 实例的 API 与模块级函数一一对应,只是使用编译好的格式:
| 方法 | 说明 |
|---|---|
pack(v1, v2, ...) |
等价于模块级 pack,且 len(result) 恒等于 self.size |
pack_into(buffer, offset, v1, v2, ...) |
等价于模块级 pack_into |
unpack(buffer) |
等价于模块级 unpack;缓冲区字节数必须等于 self.size |
unpack_from(buffer, offset=0) |
等价于模块级 unpack_from;从 offset 起的剩余字节数必须至少为 self.size |
iter_unpack(buffer) |
等价于模块级 iter_unpack;缓冲区字节数必须是 self.size 的整数倍(3.4 起) |
实例属性:
format:构造该对象所用的格式字符串(Python 3.7 起该属性类型是str而非bytes);size:格式串对应的结构大小(即pack方法产出 bytes 的长度)。
Python 3.13 起 Struct 的 repr() 显示为构造表达式形式:
>>> struct.Struct('i')
Struct('i')
性能对比示例
>>> from struct import Struct
>>> s = Struct('<10sHHb') # 编译一次
>>> s.size
15
>>> s.pack(b'raymond ', 0x1232, 0x0108, 8)
b'raymond \x32\x12\x08\x01\x08'
>>> s.unpack(b'raymond \x32\x12\x08\x01\x08')
(b'raymond ', 4658, 264, 8)
>>> list(s.iter_unpack(b'raymond \x32\x12\x08\x01\x08' * 2))
[(b'raymond ', 4658, 264, 8), (b'raymond ', 4658, 264, 8)]
C 层实现要点补充
把官方文档与 Modules/_struct.c 对照阅读,可以更准确地理解模块行为背后的机制:
- 表驱动翻译:每种格式字符的 pack/unpack 都是独立的小函数,native 模式用小端机器上会被编译器优化掉的
memcpy中间变量读取(native 例程注释说明见 Modules/_struct.c),而大端/小端模式则逐字节移位拼装(例如bu_int的x = (x<<8) | *bytes++循环,见 Modules/_struct.c),从而保证无论宿主机字节序如何都能产出正确结果。 - 范围校验:对越界整数,
_range_error()依据字段字节宽度动态构造错误消息并抛StructError。 __index__协议:非整数输入先经get_pylong()尝试通过索引协议转换为整数,这也是文档注 (2) 的行为来源。- 迭代器实现:
iter_unpack返回的迭代器对象实现了__length_hint__与标准的tp_iternext,配合预取逻辑让逐块解包接近纯 C 速度。 - 两套类型表:native 模式使用基于
sizeof/_Alignof的native_table;standard 模式则把h、i、l、q、f、d等统一固定为 2/4/4/8/4/8 等标准宽度,这正是@与=语义差异的根源。
官方测试与验证入口
如果希望在自己的环境里快速验证本文所有行为,可以直接运行 CPython 的 struct 回归测试套件:
./python -m test test_struct
对应的测试源码为 Lib/test/test_struct.py,覆盖了各字节序组合、native/standard 尺寸差异、边界值溢出、pack_into/unpack_from 的偏移语义、iter_unpack、Struct 类的缓存与清理等全部行为,是理解格式串细节的最佳第二手资料。
相关标准库与生态对比
官方文档特别提示,以下模块也使用相似但略有不同的类型码(读取二进制数据时可作为 struct 的替代或补充):
- Doc/library/array.rst:同质数据的紧凑二进制存储,类型码风格与
struct相近; - Doc/library/ctypes.rst:直接在 Python 中声明并操作 C 结构体(Fundamental data types),适合"把 Python 值映射成真正的 C struct"的场景;
- Doc/library/json.rst 与 Doc/library/pickle.rst:分别提供基于文本的自描述格式与 Python 对象序列化,二者都不面向"紧凑的定长二进制协议"。
需要把握的选择原则:当你要对接的是文件格式或网络协议中约定好的定长二进制结构时,struct(配合 </> 前缀自管字节序与 x 填充)几乎是标准答案;当你要精确复刻某台机器上 C 结构体的内存布局时,则用默认或 @ 前缀的 native 模式,并结合 Doc/library/ctypes.rst 中的 ctypes 数据类型做交叉验证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00