Sal*_*lil 48 python collections namedtuple
为什么Python本身不支持记录类型?这是一个有一个可变版本的namedtuple的问题.
我可以用namedtuple._replace.但我需要在集合中包含这些记录,并且由于namedtuple._replace创建了另一个实例,我还需要修改快速变得混乱的集合.
背景:我有一个设备,我需要通过TCP/IP轮询它获得的属性.即它的表示是一个可变对象.
编辑:我有一组我需要轮询的设备.
编辑:我需要使用PyQt遍历显示其属性的对象.我知道我可以添加像__getitem__和的特殊方法__iter__,但我想知道是否有更简单的方法.
编辑:我更喜欢一个属性固定的类型(就像它们在我的设备中一样),但是它是可变的.
tzo*_*zot 48
你的意思是这样的?
class Record(object):
__slots__= "attribute1", "attribute2", "attribute3",
def items(self):
"dict style items"
return [
(field_name, getattr(self, field_name))
for field_name in self.__slots__]
def __iter__(self):
"iterate over fields tuple/list style"
for field_name in self.__slots__:
yield getattr(self, field_name)
def __getitem__(self, index):
"tuple/list style getitem"
return getattr(self, self.__slots__[index])
>>> r= Record()
>>> r.attribute1= "hello"
>>> r.attribute2= "there"
>>> r.attribute3= 3.14
>>> print r.items()
[('attribute1', 'hello'), ('attribute2', 'there'), ('attribute3', 3.1400000000000001)]
>>> print tuple(r)
('hello', 'there', 3.1400000000000001)
Run Code Online (Sandbox Code Playgroud)
请注意,提供的方法只是可能方法的一个示例.
你可以使用types.SimpleNamespace:
>>> import types
>>> r= types.SimpleNamespace()
>>> r.attribute1= "hello"
>>> r.attribute2= "there"
>>> r.attribute3= 3.14
Run Code Online (Sandbox Code Playgroud)
dir(r)会为你提供属性名称(.startswith("__")当然过滤掉所有).
Cam*_*ron 18
你有什么理由不能使用普通字典吗?看起来这些属性在您的特定情况下没有特定的顺序.
或者,您也可以使用类实例(具有良好的属性访问语法).__slots__如果您希望避免__dict__为每个实例创建一个,则可以使用.
我刚刚找到了"记录"的配方,它被描述为可变的命名元组.它们是使用类实现的.
更新:
既然你说顺序对你的场景很重要(并且你想要遍历所有的属性),那么OrderedDict似乎是要走的路.这是collectionsPython 2.7 标准模块的一部分; 互联网上有其他实现为Python <2.7.
要添加属性样式访问,您可以像这样对其进行子类化:
from collections import OrderedDict
class MutableNamedTuple(OrderedDict):
def __init__(self, *args, **kwargs):
super(MutableNamedTuple, self).__init__(*args, **kwargs)
self._initialized = True
def __getattr__(self, name):
try:
return self[name]
except KeyError:
raise AttributeError(name)
def __setattr__(self, name, value):
if hasattr(self, '_initialized'):
super(MutableNamedTuple, self).__setitem__(name, value)
else:
super(MutableNamedTuple, self).__setattr__(name, value)
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
>>> t = MutableNamedTuple()
>>> t.foo = u'Crazy camels!'
>>> t.bar = u'Yay, attribute access'
>>> t.foo
u'Crazy camels!'
>>> t.values()
[u'Crazy camels!', u'Yay, attribute access']
Run Code Online (Sandbox Code Playgroud)
Abb*_*fei 10
这可以使用空类和它的实例来完成,如下所示:
>>> class a(): pass
...
>>> ainstance = a()
>>> ainstance.b = 'We want Moshiach Now'
>>> ainstance.b
'We want Moshiach Now'
>>>
Run Code Online (Sandbox Code Playgroud)
有一个类似于namedtuple的库,但是可变,称为recordtype.
打包主页:http://pypi.python.org/pypi/recordtype
简单的例子:
from recordtype import recordtype
Person = recordtype('Person', 'first_name last_name phone_number')
person1 = Person('Trent', 'Steele', '637-3049')
person1.last_name = 'Terrence';
print person1
# Person(first_name=Trent, last_name=Terrence, phone_number=637-3049)
Run Code Online (Sandbox Code Playgroud)
简单的默认值示例:
Basis = recordtype('Basis', [('x', 1), ('y', 0)])
Run Code Online (Sandbox Code Playgroud)
遍历以下字段person1:
map(person1.__getattribute__, Person._fields)
Run Code Online (Sandbox Code Playgroud)
这个问题很老了,但为了完整起见,Python 3.7 的数据类几乎都是记录。
>>> from dataclasses import dataclass
>>>
>>> @dataclass
... class MyRecord:
... name: str
... age: int = -1
...
>>> rec = MyRecord('me')
>>> rec.age = 127
>>> print(rec)
MyRecord(name='me', age=127)
Run Code Online (Sandbox Code Playgroud)
attrs 第三方库为 Python 2 和 Python 3 提供了更多功能。如果需求更多地围绕您无法在本地保留的内容而不是专门仅使用 stdlib,那么供应商依赖项也没有什么问题。dephell 有一个很好的帮手可以做到这一点。