Is there a data type in Python similar to structs in C++? I like the struct feature myStruct.someName
. I know that classes have this, but I don't want to write a class everytime I need a "container" for some data.
-
3Since in C++ `struct`s and `class`es are the same thing (they only differ in default members' and inheritance access specifiers) you could just write a `class`... – Matteo Italia May 09 '11 at 23:00
-
2Generally we use a dict, where the syntax is `mydict["someName"]`. But if you define your own class once, you can then add any attribute you want to instances. – Thomas K May 09 '11 at 23:00
-
@Thomas K: You mean I can create an instance `foo` of a class `bar` and add attributes to it dynamically? Like first `foo` it is empty, then I add an attribute and then another one and so on? – Aufwind May 09 '11 at 23:04
-
3Yes. `class Struct(object): pass` `s = Struct()` `s.a = 5` `print(s.a)` prints 5. – Ponkadoodle May 09 '11 at 23:07
-
@All: Thank you all for the advices! – Aufwind May 10 '11 at 02:56
8 Answers
Why not? Classes are fine for that.
If you want to save some memory, you might also want to use __slots__
so the objects don't have a __dict__
. See http://docs.python.org/reference/datamodel.html#slots for details and Usage of __slots__? for some useful information.
For example, a class holding only two values (a
and b
) could looks like this:
class AB(object):
__slots__ = ('a', 'b')
If you actually want a dict but with obj.item
access instead of obj['item']
, you could subclass dict and implement __getattr__
and __setattr__
to behave like __getitem__
and __setitem__
.

- 1
- 1

- 310,957
- 84
- 592
- 636
-
1Thanks. I will stick with classes! :) Your suggestions of "modifying" dict is really cool! – Aufwind May 09 '11 at 23:21
-
1This is a seriously underrated answer in an obscure topic. A dict with `__getattr__` and `__setattr__` functions seems to me like a very elegant way to implement struct-like behaviour in python. – kadu Sep 03 '14 at 15:54
In addition to the dict type, there is a namedtuple type that behaves somewhat like a struct.
MyStruct = namedtuple('MyStruct', ['someName', 'anotherName'])
aStruct = MyStruct('aValue', 'anotherValue')
print aStruct.someName, aStruct.anotherName

- 1,054
- 2
- 8
- 17
-
This reminds me of "user defined types" from Visual Basic 6.0. They were VB's analog to C++'s struct. Even the way it is declared is similar. http://www.vb6.us/tutorials/user-defined-types-udt-vb – Neamerjell May 29 '16 at 08:04
-
2Note that a `namedtuple` is read-only, i.e. you cannot change values like `aStruct.someName = "foo"` (of course this is consistent with normal tuples). – luator Jun 28 '17 at 12:10
dataclass
is now built-in to Python as of Python 3.7!
from dataclasses import dataclass
@dataclass
class EZClass:
name: str='default'
qty: int
Test:
classy = EZClass('cars', 3)
print(classy)
Output:
EZClass(name='cars', qty=3)
Besides for the automatic initialization and __repr__
methods which it generates, it also automatically creates an __eq__
method to make it simple and intuitive to compare two instances of the class.
See PEP 557.
Backported to Python 3.6 using the dataclasses package.

- 7,024
- 4
- 38
- 46
Please realise that in C++, the only difference between a class and a struct is that the elements of a class are by default private, as is the inheritance. The following are equivalent:
class D : public B {
public:
...
};
struct D {
...
};
In Python, it would make most sense to use a class if you want to use the dot operator to access elements. In fact, it's even easier, as you only have to initialise the members you currently want, and can add/remove members later. Therefore, the following would work:
class D(object):
pass
You can then add as many members as you want simply by assigning to them.

- 3,474
- 1
- 21
- 41
-
Thanks you for the detailed explanation. The idea behind my question is readability of my code. This will help a lot! – Aufwind May 09 '11 at 23:17
-
1
-
1Classes without methods (dump classes) are considered an anti-pattern, as far as I can tell. – stelios Feb 04 '17 at 18:08
You can always go for the dynamic approach:
class foo(object):
def __init__(self,**kwargs):
self.__dict__.update(kwargs)
This'll make a class with the same methods that you pass in as a dict:
bar = foo(bill="yo",heather="hi",sam="piss off")
leaving you with the following perfectly valid calls on bar
:
bar.bill
>> "yo"
bar.heater
>> "hi"
you get the idea...

- 35,646
- 15
- 94
- 131
I believe you're looking for a dict
.
d = dict({
'name': 'myname',
'val': 'myval'
})
print d
print d['name']

- 21,135
- 5
- 42
- 46
This may be taking the idea a bit too far, but here's a way to create "structs" using a syntax that's kinda similar to C++ structs that also does some type checking. First, here's an example of using it:
>>> MyStruct = Struct({
... 'i': int,
... 's': str,
... 'x': float,
... }, 'MyStruct')
>>> print(MyStruct)
MyStruct {
i: int,
s: str,
x: float,
}
>>> instance = MyStruct(i=1, s='s', x=1.0)
>>> print(instance)
MyStruct(i: 1, s: 's', x: 1.0)
And here's the implementation. It's a variation of the __slots__
idea where the class with slots (i.e., the "struct" type) is generated dynamically. This could of course be fleshed out in various ways, but this is just a proof of concept.
class Struct:
class StructInstance:
__slots__ = ()
def __str__(self):
values = []
for name in self.__slots__:
value = getattr(self, name)
values.append('{name}: {value!r}'.format(name=name, value=value))
type_name = self.__class__.__name__
values = ', '.join(values)
return '{type_name}({values})'.format(type_name=type_name, values=values)
def __init__(self, fields, name=None):
for field_name, field_type in fields.items():
assert isinstance(field_name, str), 'Expected str for field name'
assert isinstance(field_type, type), 'Expected type for field type'
self.fields = fields
self.name = name or 'Struct'
self.type = type(
self.name, (self.StructInstance,), {'__slots__': tuple(fields)})
def __call__(self, **values):
instance = self.type()
for name in instance.__slots__:
value = values[name]
expected_type = self.fields[name]
assert isinstance(value, expected_type), 'Expected %s for %s' % (expected_type, name)
setattr(instance, name, value)
return instance
def __str__(self):
fields = [' {n}: {t.__name__},'.format(n=n, t=t) for n, t in self.fields.items()]
return '{name} {{\n{fields}\n}}'.format(name=self.name, fields='\n'.join(fields))