Python中的C类结构
有没有什么简单的方法可以在Python中定义类似C语言的结构体?我已经厌倦了写这样的东西:
class MyStruct():
def __init__(self, field1, field2, field3):
self.field1 = field1
self.field2 = field2
self.field3 = field3
28 个回答
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'))