Python中的类C结构?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (10)
  • 关注 (0)
  • 查看 (170)

有没有一种方法可以方便地在Python中定义一个类似C的结构?我厌倦了写这样的东西:

class MyStruct():
    def __init__(self, field1, field2, field3):
        self.field1 = field1
        self.field2 = field2
        self.field3 = field3
提问于
用户回答回答于

Python 3.6它变得相当简单:

声明如下:(注意,这允许类型注释)

from typing import NamedTuple

class MyStruct(NamedTuple):
    my_string: str
    my_int: int
    my_list: list
    my_dict: dict
    my_foo: Foo

像这样使用它:

my_item = MyStruct(
    my_string='foo',
    my_int=0,
    my_list=['bar'],
    my_dict={'baz': 'qux'},
    my_foo=Foo('bar')
)

或者像这样:

my_item = MyStruct('foo', 0, ['bar'], {'baz': 'qux'}, Foo('bar'))
用户回答回答于

您可以通过以下方式访问python中的C样式结构。

class cstruct:
    var_i = 0
    var_f = 0.0
    var_str = ""

如果您只想使用cstruct的对象

obj = cstruct()
obj.var_i = 50
obj.var_f = 50.00
obj.var_str = "fifty"
print "cstruct: obj i=%d f=%f s=%s" %(obj.var_i, obj.var_f, obj.var_str)

如果要创建cstruct的对象数组

obj_array = [cstruct() for i in range(10)]
obj_array[0].var_i = 10
obj_array[0].var_f = 10.00
obj_array[0].var_str = "ten"

#go ahead and fill rest of array instaces of struct

#print all the value
for i in range(10):
    print "cstruct: obj_array i=%d f=%f s=%s" %(obj_array[i].var_i, obj_array[i].var_f, obj_array[i].var_str)

注意:请用您的结构名代替“cstruct”名称,而不是var_i, var_f, var_str,请定义结构的成员变量。

用户回答回答于

每当我需要一个“即时数据对象,它的行为也像一个字典”(我不认为是C结构!),我想到这个黑客:

class Map(dict):
    def __init__(self, **kwargs):
        super(Map, self).__init__(**kwargs)
        self.__dict__ = self

现在你可以说:

struct = Map(field1='foo', field2='bar', field3=42)

self.assertEquals('bar', struct.field2)
self.assertEquals(42, struct['field3'])

当你需要一个“不是一个类的数据包”时,以及当namedtuples不可理解的时候,这是非常方便的。

用户回答回答于

您可以对标准库中可用的C结构进行子类化。ctypes模块提供了一个结构类.文档中的示例:

>>> from ctypes import *
>>> class POINT(Structure):
...     _fields_ = [("x", c_int),
...                 ("y", c_int)]
...
>>> point = POINT(10, 20)
>>> print point.x, point.y
10 20
>>> point = POINT(y=5)
>>> print point.x, point.y
0 5
>>> POINT(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: too many initializers
>>>
>>> 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
>>>
用户回答回答于

还可以按位置将init参数传递给实例变量。

# Abstract struct class       
class Struct:
    def __init__ (self, *argv, **argd):
        if len(argd):
            # Update by dictionary
            self.__dict__.update (argd)
        else:
            # Update by position
            attrs = filter (lambda x: x[0:2] != "__", dir(self))
            for n in range(len(argv)):
                setattr(self, attrs[n], argv[n])

# Specific class
class Point3dStruct (Struct):
    x = 0
    y = 0
    z = 0

pt1 = Point3dStruct()
pt1.x = 10

print pt1.x
print "-"*10

pt2 = Point3dStruct(5, 6)

print pt2.x, pt2.y
print "-"*10

pt3 = Point3dStruct (x=1, y=2, z=3)
print pt3.x, pt3.y, pt3.z
print "-"*10
用户回答回答于

DF:这很酷...我不知道我可以用DECT访问类中的字段。 马克:我希望我有这样的情况,就是我想要一个元组,但没有什么像字典那样“heavy”。

您可以使用字典访问类的字段,因为类的字段、方法及其所有属性都是使用dicts(至少在CPython中)在内部存储的。

这就引出了你的第二条评论。相信Python dicts是“heavy”是一个非常非Python的概念。读到这样的评论会扼杀我的Python zen。这可不好。

您知道,当您声明一个类时,您实际上是在为一个字典创建一个相当复杂的包装器--所以,如果有的话,您所增加的开销要比使用一个简单的字典要多。顺便说一句,这种开销在任何情况下都是毫无意义的。如果您正在处理性能关键的应用程序,请使用C或其他语言。

用户回答回答于

字典怎么样?

就像这样:

myStruct = {'field1': 'some val', 'field2': 'some val'}

然后您可以使用它来操作值:

print myStruct['field1']
myStruct['field2'] = 'some other values'

而这些值不一定是字符串。它们几乎可以是任何其他对象。

用户回答回答于

也许您正在寻找没有构造函数的结构:

class Sample:
  name = ''
  average = 0.0
  values = None # list cannot be initialized here!


s1 = Sample()
s1.name = "sample 1"
s1.values = []
s1.values.append(1)
s1.values.append(2)
s1.values.append(3)

s2 = Sample()
s2.name = "sample 2"
s2.values = []
s2.values.append(4)

for v in s1.values:   # prints 1,2,3 --> OK.
  print v
print "***"
for v in s2.values:   # prints 4 --> OK.
  print v
用户回答回答于

您可以使用元组在C中使用结构(例如x、y坐标或RGB颜色)。

对于其他任何东西,您都可以使用字典,或者类似于这个:

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

我认为“决定性”的讨论是这儿,在PythonCookbook的发布版本中。

用户回答回答于

命名元组,它被添加到集合模块在Python2.6的标准库中。也可以用命名元组如果您需要支持Python2.4的话。

它对您的基本示例很适用,但也涵盖了您稍后可能遇到的一些边缘情况。上面的片段将写成:

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

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

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

还可以使用命名参数:

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

扫码关注云+社区

领取腾讯云代金券