Python中的C类结构

675 投票
28 回答
898924 浏览
提问于 2025-04-11 09:18

有没有什么简单的方法可以在Python中定义类似C语言的结构体?我已经厌倦了写这样的东西:

class MyStruct():
    def __init__(self, field1, field2, field3):
        self.field1 = field1
        self.field2 = field2
        self.field3 = field3

28 个回答

107

你可以用元组来做很多事情,就像在C语言中用结构体一样,比如表示坐标(x,y)或者RGB颜色。

对于其他的情况,你可以使用字典,或者像这个工具类

>>> class Bunch:
...     def __init__(self, **kwds):
...         self.__dict__.update(kwds)
...
>>> mystruct = Bunch(field1=value1, field2=value2)

我觉得关于这个话题的“权威”讨论可以在这里找到,内容在《Python Cookbook》的出版版本中。

387

使用一个叫做 命名元组 的东西,这个功能是在 Python 2.6 的标准库中的 collections 模块 里新增的。如果你需要支持 Python 2.4 版本,也可以使用 Raymond Hettinger 的 命名元组 的做法。

这个命名元组对于你的基本示例来说非常好用,同时也能处理一些你将来可能遇到的特殊情况。你上面的代码片段可以这样写:

from collections import namedtuple
MyStruct = namedtuple("MyStruct", "field1 field2 field3")

新创建的类型可以这样使用:

m = MyStruct("foo", "bar", "baz")

你还可以使用命名参数:

m = MyStruct(field1="foo", field2="bar", field3="baz")
579

更新: 数据类

Python 3.7中引入了数据类,这让我们离目标更近了一步。

下面的例子和下面的命名元组例子类似,但生成的对象是可变的,而且可以设置默认值。

from dataclasses import dataclass


@dataclass
class Point:
    x: float
    y: float
    z: float = 0.0


p = Point(1.5, 2.5)

print(p)  # Point(x=1.5, y=2.5, z=0.0)

这和新的类型模块配合得很好,如果你想使用更具体的类型注释的话。

我一直在迫切等待这个!如果你问我,数据类和新的命名元组声明,再加上类型模块,简直是天赐良机!

改进的命名元组声明

自从Python 3.6以来,声明变得相当简单和美观(在我看来),只要你能接受不可变性

引入了一种新的命名元组声明方式,这也允许使用类型注释

from typing import NamedTuple


class User(NamedTuple):
    name: str


class MyStruct(NamedTuple):
    foo: str
    bar: int
    baz: list
    qux: User


my_item = MyStruct('foo', 0, ['baz'], User('peter'))

print(my_item) # MyStruct(foo='foo', bar=0, baz=['baz'], qux=User(name='peter'))

撰写回答