Python类作为数据存储
我正在尝试编写一个类似于某种数据存储的Python类。因此,我不想使用字典,而是希望以class.foo的形式访问我的数据,并且仍然能够像在dataclass中对x那样对其进行迭代 以下是我的想法:Python类作为数据存储,python,attributes,setattr,Python,Attributes,Setattr,我正在尝试编写一个类似于某种数据存储的Python类。因此,我不想使用字典,而是希望以class.foo的形式访问我的数据,并且仍然能够像在dataclass中对x那样对其进行迭代 以下是我的想法: class MyStore(object): def __init__(self, data): self._data = {} for d in data: # Just for the sake of example
class MyStore(object):
def __init__(self, data):
self._data = {}
for d in data:
# Just for the sake of example
self._data[d] = d.upper()
def __iter__(self):
return self._data.values().__iter__()
def __len__(self):
return len(self._data)
def __contains__(self, name):
return name in self._data
def __getitem__(self, name):
return self._data[name]
def __getattr__(self, name):
return self._data[name]
store = MyStore(['foo', 'bar', 'spam', 'eggs'])
print "Store items:", [item for item in store]
print "Number of items:", len(store)
print "Get item:", store['foo']
print "Get attribute:", store.foo
print "'foo' is in store:", 'foo' in store
而且,很明显,它是有效的。好极了但是如何正确地实现属性的设置呢?在\uuu getattr\uuuu
上添加以下内容将导致递归限制:
def __setattr__(self, name, value):
self._data[name] = value
阅读文档时,我应该调用超类(object)\uuuu setattr\uuuu
方法以避免递归,但这样我就无法控制自己
有人能给我指出正确的方向吗?试试这个:
def __setattr__(self, name, value):
super(MyStore, self).__setattr__(name, value)
self._data[name] = value
但是,只需将类似于
dict
的内容子类化,就可以省去很多麻烦:
class MyStore(dict):
def __init__(self, data):
for d in data:
self[d] = d.upper()
def __getattr__(self, name):
return self[name]
def __setattr__(self, name, value):
self[name] = value
store = MyStore(['foo', 'bar', 'spam', 'eggs'])
print "Store items:", [item for item in store]
print "Number of items:", len(store)
print "Get item:", store['foo']
print "Get attribute:", store.foo
print "'foo' is in store:", 'foo' in store
store.qux = 'QUX'
print "Get qux item:", store['qux']
print "Get qux attribute:", store.qux
print "'qux' is in store:", 'qux' in store
哪个输出
Store items: ['eggs', 'foo', 'bar', 'spam']
Number of items: 4
Get item: FOO
Get attribute: FOO
'foo' is in store: True
Get qux item: QUX
Get qux attribute: QUX
'qux' is in store: True
试试这个:
def __setattr__(self, name, value):
super(MyStore, self).__setattr__(name, value)
self._data[name] = value
但是,只需将类似于
dict
的内容子类化,就可以省去很多麻烦:
class MyStore(dict):
def __init__(self, data):
for d in data:
self[d] = d.upper()
def __getattr__(self, name):
return self[name]
def __setattr__(self, name, value):
self[name] = value
store = MyStore(['foo', 'bar', 'spam', 'eggs'])
print "Store items:", [item for item in store]
print "Number of items:", len(store)
print "Get item:", store['foo']
print "Get attribute:", store.foo
print "'foo' is in store:", 'foo' in store
store.qux = 'QUX'
print "Get qux item:", store['qux']
print "Get qux attribute:", store.qux
print "'qux' is in store:", 'qux' in store
哪个输出
Store items: ['eggs', 'foo', 'bar', 'spam']
Number of items: 4
Get item: FOO
Get attribute: FOO
'foo' is in store: True
Get qux item: QUX
Get qux attribute: QUX
'qux' is in store: True
为什么不直接将迭代内容添加到普通对象中,并使用其
\uuuuu dict\uuuuuu
而不是您的dict?您可以使用sys.setrecursionlimit()
增加递归限制,顺便说一句。为什么不直接将迭代内容添加到普通对象中,并使用它的\uuuu dict\uuuuu
代替您的dict?您可以使用sys.setrecursionlimit()
增加递归限制,顺便说一句,子类化dict确实节省了我的工作。我只需要从问题中添加\uuuu iter\uuu
方法,这样在迭代类时就可以得到值而不是键。谢谢当然,尽管您正在创建一个类似于dict的结构,该结构具有键和值,但如果您想在值上进行迭代,那么将迭代留在键上并使用已经提供的.itervalues()
方法可能更有意义。:)这很公平,但因为我总是对类创建后的值感兴趣,所以我不用调用.itervalues()
。您的评论使我将返回行更改为return self.itervalues()
,但是,它看起来更好。啊哈,子类化dict确实节省了我的工作。我只需要从问题中添加\uuuu iter\uuu
方法,这样在迭代类时就可以得到值而不是键。谢谢当然,尽管您正在创建一个类似于dict的结构,该结构具有键和值,但如果您想在值上进行迭代,那么将迭代留在键上并使用已经提供的.itervalues()
方法可能更有意义。:)这很公平,但因为我总是对类创建后的值感兴趣,所以我不用调用.itervalues()
。您的评论使我将返回行更改为return self.itervalues()
,但看起来更好。