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