Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python类作为数据存储_Python_Attributes_Setattr - Fatal编程技术网

Python类作为数据存储

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

我正在尝试编写一个类似于某种数据存储的Python类。因此,我不想使用字典,而是希望以class.foo的形式访问我的数据,并且仍然能够像在dataclass中对x那样对其进行迭代

以下是我的想法:

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()
,但看起来更好。