Python中的数据类型是否类似于C ++中的结构?

时间:2011-05-09 22:56:49

标签: c++ python types struct

Python中的数据类型是否与C ++中的结构相似?我喜欢结构特征myStruct.someName。我知道类有这个,但我不想每次为某些数据需要一个“容器”时编写一个类。

8 个答案:

答案 0 :(得分:31)

为什么不呢?课程很好。

如果要保存一些内存,可能还需要使用__slots__,因此对象没有__dict__。有关详细信息,请参阅http://docs.python.org/reference/datamodel.html#slots;有关有用信息,请参见Usage of __slots__?

例如,只包含两个值(ab)的类可能如下所示:

class AB(object):
    __slots__ = ('a', 'b')

如果你真的想要一个dict但obj.item访问而不是obj['item'],你可以继承dict并实现__getattr____setattr__,就像__getitem__一样和__setitem__

答案 1 :(得分:14)

除了dict类型之外,还有一个namedtuple类型,其行为有点像结构。

MyStruct = namedtuple('MyStruct', ['someName', 'anotherName'])
aStruct = MyStruct('aValue', 'anotherValue')

print aStruct.someName, aStruct.anotherName

答案 2 :(得分:6)

请注意,在C ++中,类和结构之间的唯一区别是类的元素默认是私有的,继承也是如此。以下是等效的:

class D : public B {
    public:
    ...
}; 

struct D {
    ...
};

在Python中,如果要使用点运算符来访问元素,最有必要使用类。事实上,它更容易,因为您只需初始化您当前想要的成员,并可以在以后添加/删除成员。因此,以下方法可行:

class D(object):
    pass

然后,您可以根据需要添加任意数量的成员。

答案 3 :(得分:5)

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.

答案 4 :(得分:4)

您可以随时采用动态方法:

class foo(object):
    def __init__(self,**kwargs):
        self.__dict__.update(kwargs)

这将使用与dict传递相同的方法创建一个类:

bar = foo(bill="yo",heather="hi",sam="piss off")

bar上留下以下完全有效的来电:

bar.bill
>> "yo"
bar.heater
>> "hi"

你明白了......

答案 5 :(得分:3)

尝试使用dict

这是一个简单的演示。

>>> something = {}
>>> something['x'] = 42
>>> something['y'] = 'cheese'
>>> something
{'y': 'cheese', 'x': 42}
>>> something['x']
42
>>> something['y']
'cheese'

答案 6 :(得分:2)

我相信你正在寻找dict

d = dict({
        'name': 'myname',
        'val': 'myval'
        })

print d
print d['name']

答案 7 :(得分:1)

这可能会让这个想法有点过分,但这是一种创造"结构"使用类似于C ++结构的语法,它也进行某些类型检查。首先,这是一个使用它的例子:

>>> 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)

以下是实施方案。它是__slots__想法的变体,其中带有插槽的类(即" struct"类型)是动态生成的。这当然可以通过各种方式充实,但这只是一个概念证明。

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))