python file API
Thomas Rachel
nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915 at spamschutz.glglgl.de
Tue Sep 25 01:25:48 EDT 2012
Am 25.09.2012 04:28 schrieb Steven D'Aprano:
> By the way, the implementation of this is probably trivial in Python 2.x.
> Untested:
>
> class MyFile(file):
> @property
> def pos(self):
> return self.tell()
> @pos.setter
> def pos(self, p):
> if p< 0:
> self.seek(p, 2)
> else:
> self.seek(p)
>
> You could even use a magic sentinel to mean "see to EOF", say, None.
>
> if p is None:
> self.seek(0, 2)
>
> although I don't know if I like that.
The whole concept is incomplete at one place: self.seek(10, 2) seeks
beyond EOF, potentially creating a sparse file. This is a thing you
cannot achieve.
But the idea is great. I'd suggest to have another property:
[...]
@pos.setter
def pos(self, p):
self.seek(p)
@property
def eofpos(self): # to be consistent
return self.tell()
@eofpos.setter
def eofpos(self, p):
self.seek(p, 2)
Another option could be a special descriptor which can be used as well
for relative seeking:
class FilePositionDesc(object):
def __init__(self):
pass
def __get__(self, instance, owner):
return FilePosition(self)
def __set__(self, value):
self.seek(value)
class FilePosition(object):
def __init__(self, file):
self.file = file
def __iadd__(self, offset):
self.file.seek(offset, 1)
def __isub__(self, offset):
self.file.seek(-offset, 1)
class MyFile(file):
pos = FilePositionDesc()
[...]
Stop.
This could be handled with a property as well.
Besides, this breaks some other expectations to the pos. So let's
introduce a 3rd property named relpos:
class FilePosition(object):
def __init__(self, file):
self.file = file
self.seekoffset = 0
def __iadd__(self, offset):
self.seekoffset += offset
def __isub__(self, offset):
self.seekoffset -= offset
def __int__(self):
return self.file.tell() + self.seekoffset
class MyFile(file):
@property
def relpos(self):
return FilePosition(self) # from above
@relpos.setter
def relpos(self, ofs):
try:
o = ofs.seekoffset # is it a FilePosition?
except AttributeError:
self.seek(ofs, 1) # no, but ofs can be an int as well
else:
self.seek(o, 1) # yes, it is
Thomas
More information about the Python-list
mailing list