是否有一种方法可以方便地在Python中定义类c结构?我厌倦了写这样的东西:
class MyStruct():
def __init__(self, field1, field2, field3):
self.field1 = field1
self.field2 = field2
self.field3 = field3
是否有一种方法可以方便地在Python中定义类c结构?我厌倦了写这样的东西:
class MyStruct():
def __init__(self, field1, field2, field3):
self.field1 = field1
self.field2 = field2
self.field3 = field3
当前回答
还可以按位置将初始化参数传递给实例变量
# 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
其他回答
您可以子类化标准库中可用的C结构。ctypes模块提供了一个Structure类。文档中的例子:
>>> 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
>>>
更新:数据类
随着Python 3.7中数据类的引入,我们已经非常接近了。
下面的示例与下面的NamedTuple示例类似,但是生成的对象是可变的,并且允许使用默认值。
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)
如果您想使用更特定的类型注释,这可以很好地配合新的类型模块。
我一直在绝望地等待这一刻!要我说,Data Classes和新的NamedTuple声明,再加上typing模块,简直就是天赐之物!
改进的NamedTuple声明
自从Python 3.6以来,它变得非常简单和美丽(恕我直言),只要你能忍受不变性。
引入了一种声明NamedTuples的新方法,它也允许类型注释:
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'))
一本字典怎么样?
就像这样:
myStruct = {'field1': 'some val', 'field2': 'some val'}
然后你可以使用这个来操作值:
print myStruct['field1']
myStruct['field2'] = 'some other values'
值不一定是字符串。它们可以是其他任何物体。
这里有一个解决方案,它使用一个类(从未实例化)来保存数据。我喜欢这种方式涉及很少的输入,不需要任何额外的软件包等。
class myStruct:
field1 = "one"
field2 = "2"
您可以稍后根据需要添加更多字段:
myStruct.field3 = 3
要获取值,可以像往常一样访问字段:
>>> myStruct.field1
'one'
就我个人而言,我也喜欢这种变体。它扩展了@dF的答案。
class struct:
def __init__(self, *sequential, **named):
fields = dict(zip(sequential, [None]*len(sequential)), **named)
self.__dict__.update(fields)
def __repr__(self):
return str(self.__dict__)
它支持两种初始化模式(可以混合使用):
# Struct with field1, field2, field3 that are initialized to None.
mystruct1 = struct("field1", "field2", "field3")
# Struct with field1, field2, field3 that are initialized according to arguments.
mystruct2 = struct(field1=1, field2=2, field3=3)
而且,它打印得更好:
print(mystruct2)
# Prints: {'field3': 3, 'field1': 1, 'field2': 2}