Python中如何实现结构体内嵌结构体?

C 代码类似

struct IMAGE_NT_HEADERS {
    IMAGE_OPTIONAL_HEADER IMAGE_OPTIONAL_HEADER {
    }
}
struct IMAGE_OPTIONAL_HEADER{....}

_(:з)∠)_。。。Python 如何做到呢?用 ctypes 没想出来怎么做


Python中如何实现结构体内嵌结构体?
2 回复

Python里没有C语言那种原生的struct。不过,要实现结构体内嵌结构体,用dataclasses或者namedtuple都很直观。

方法一:用dataclasses (Python 3.7+ 推荐) dataclass自动生成__init____repr__这些方法,写起来最省事。

from dataclasses import dataclass

@dataclass
class Point:
    x: float
    y: float

@dataclass
class Line:
    start: Point  # 内嵌Point结构体
    end: Point    # 内嵌另一个Point结构体

# 使用
p1 = Point(0.0, 0.0)
p2 = Point(1.0, 2.0)
line = Line(start=p1, end=p2)
print(line)           # 输出: Line(start=Point(x=0.0, y=0.0), end=Point(x=1.0, y=2.0))
print(line.start.x)   # 输出: 0.0

方法二:用namedtuple 如果结构体是只读的、轻量的,用collections.namedtuple也行,内存开销小。

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
Line = namedtuple('Line', ['start', 'end'])

p1 = Point(0.0, 0.0)
p2 = Point(1.0, 2.0)
line = Line(start=p1, end=p2)
print(line)           # 输出: Line(start=Point(x=0.0, y=0.0), end=Point(x=1.0, y=2.0))
print(line.start.x)   # 输出: 0.0

方法三:普通类 当然,直接用普通类手动写__init__也行,就是代码多点。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Line:
    def __init__(self, start, end):
        self.start = start
        self.end = end

p1 = Point(0.0, 0.0)
p2 = Point(1.0, 2.0)
line = Line(p1, p2)

总结建议 现在写Python结构体,无脑用dataclass就行。


https://docs.python.org/2/library/ctypes.html#structures-and-unions

You can, however, build much more complicated structures. A structure can itself contain other structures by using a structure as a field type.

Here is a RECT structure which contains two POINTs named upperleft and lowerright:

>>>
>>> class RECT(Structure):
fields = [(“upperleft”, POINT),
… (“lowerright”, POINT)]

>>> rc = RECT(point)
>>> print rc.upperleft.x, rc.upperleft.y
0 5
>>> print rc.lowerright.x, rc.lowerright.y
0 0
>>>
Nested structures can also be initialized in the constructor in several ways:

>>>
>>> r = RECT(POINT(1, 2), POINT(3, 4))
>>> r = RECT((1, 2), (3, 4))

回到顶部