可变@属性?
Mutable @property?
有没有办法在 Python 中定义 MUTABLE(不仅仅是可重新分配!)属性?我需要一个 属性,returns 文件中的一个列表,并在所述列表上使用 __setitem__
时更改所述文件。
无效的示例:
>>> import mmap
>>> def someClass():
def __init__(self, fileName):
self.fileName = fileName
@property
def data(self):
"""Return data at start of eil in 4 byte chunks"""
with open(self.fileName, mode = 'r+b') as f:
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as fmap:
data = [fmap[i:i+4] for i in range(1024)]
return data
@data.setter
def data(self, value):
"""Save data to file"""
with open(self.fileName, mode = 'w+b') as f:
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_WRITE) as fmap:
for i, data in enumerate(value):
fmap[i:i+4] = data
>>> a = someClass('C:\test.txt')
>>> a.data[0] == a.data[1]
False
>>> a.data[0] = a.data[1]
>>> a.data[0] == a.data[1]
False # Mutation did not register to file
我真的对 mmap
一无所知,所以我可能会弄乱那里的逻辑,但总体思路是一样的。
正如@jasonharper 在评论中所建议的那样,sulotion 是创建一个定义 __setitem__
的自定义 class 并将其用于 someClass().data
.
class FileUpdatingList:
def __init__(self, filename):
self.filename = filename
def __getitem__(self, index):
with open(self.fileName, mode = 'r+b') as f:
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as fmap:
return fmap[index:index+4]
def __setitem__(self, index, data):
with open(self.fileName, mode = 'w+b') as f:
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_WRITE) as fmap:
fmap[index:index+4] = data
现在的问题是 someClass().data = value
不再有效,您必须使用 someClass.data[:] = value
。要解决这个问题,你可以写一个 属性 来为你做这个:
def someClass():
def __init__(self, fileName):
self.fileName = fileName
self._data = FileUpdatingList(filename)
@property
def data(self):
"""Return data at start of eil in 4 byte chunks"""
return self._data
@data.setter
def data(self, value):
"""Save data to file"""
self._data[:] = value
有没有办法在 Python 中定义 MUTABLE(不仅仅是可重新分配!)属性?我需要一个 属性,returns 文件中的一个列表,并在所述列表上使用 __setitem__
时更改所述文件。
无效的示例:
>>> import mmap
>>> def someClass():
def __init__(self, fileName):
self.fileName = fileName
@property
def data(self):
"""Return data at start of eil in 4 byte chunks"""
with open(self.fileName, mode = 'r+b') as f:
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as fmap:
data = [fmap[i:i+4] for i in range(1024)]
return data
@data.setter
def data(self, value):
"""Save data to file"""
with open(self.fileName, mode = 'w+b') as f:
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_WRITE) as fmap:
for i, data in enumerate(value):
fmap[i:i+4] = data
>>> a = someClass('C:\test.txt')
>>> a.data[0] == a.data[1]
False
>>> a.data[0] = a.data[1]
>>> a.data[0] == a.data[1]
False # Mutation did not register to file
我真的对 mmap
一无所知,所以我可能会弄乱那里的逻辑,但总体思路是一样的。
正如@jasonharper 在评论中所建议的那样,sulotion 是创建一个定义 __setitem__
的自定义 class 并将其用于 someClass().data
.
class FileUpdatingList:
def __init__(self, filename):
self.filename = filename
def __getitem__(self, index):
with open(self.fileName, mode = 'r+b') as f:
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as fmap:
return fmap[index:index+4]
def __setitem__(self, index, data):
with open(self.fileName, mode = 'w+b') as f:
with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_WRITE) as fmap:
fmap[index:index+4] = data
现在的问题是 someClass().data = value
不再有效,您必须使用 someClass.data[:] = value
。要解决这个问题,你可以写一个 属性 来为你做这个:
def someClass():
def __init__(self, fileName):
self.fileName = fileName
self._data = FileUpdatingList(filename)
@property
def data(self):
"""Return data at start of eil in 4 byte chunks"""
return self._data
@data.setter
def data(self, value):
"""Save data to file"""
self._data[:] = value