Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to subclass file

0 views
Skip to first unread message

Yves Dorfsman

unread,
May 14, 2008, 8:23:26 PM5/14/08
to
I want to create a subclass of 'file' but need to open the file with os.open
(because I want to open it in exclusive mode), and need an additional method.

Because I need an additional method, I truly need a object of my sublass.
If I do something like

class myFile(file):

def __new__(cls, filename):
import os
fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_EXCL)

return os.fdoen(fd, 'w')

def myMethod(self):
do_something


then x = myFile('somefilename') is of type file, not myFile, and therefore
does not have myMethod as a valid method.

Now if I try:

class myFile(file):

def __new__(cls, filename):
import os
fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_EXCL)

obj = file.__new__(cls)

return obj

def myMethod(self):
do_something

Then it fails, because the 'file' constructor needs a filename. I can provide
the filename, but it will then try to re-open that file, and even if I did
manage to create an object file, how do I connect the file descriptor created
by os.open to my object ?


Thanks.


Yves.
http://www.SollerS.ca

Gabriel Genellina

unread,
May 15, 2008, 5:43:51 AM5/15/08
to pytho...@python.org
En Wed, 14 May 2008 21:23:26 -0300, Yves Dorfsman <yv...@zioup.com>
escribió:

> I want to create a subclass of 'file' but need to open the file with
> os.open
> (because I want to open it in exclusive mode), and need an additional
> method.
>
> Because I need an additional method, I truly need a object of my sublass.
> If I do something like
>
> class myFile(file):
>
> def __new__(cls, filename):
> import os
> fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
> return os.fdoen(fd, 'w')
>
> def myMethod(self):
> do_something
>
>
> then x = myFile('somefilename') is of type file, not myFile, and
> therefore
> does not have myMethod as a valid method.

Use delegation instead of inheritance.

from __future__ import with_statement
import os

class myFile(object):
__slots__ = ['_file']

def __init__(self, filename):


fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_EXCL)

f = os.fdopen(fd, 'w')
object.__setattr__(self, '_file', f)

def __getattr__(self, name):
return getattr(self._file, name)

def __setattr__(self, name, value):
setattr(self._file, name, value)

def mymethod(self):
print "anything"


<output>
py> regular_file = open(r"c:\\temp\\regular.txt", "wt")
py> special_file = myFile(r"c:\\temp\\special.txt")
py> print regular_file
<open file 'c:\\temp\\regular.txt', mode 'wt' at 0x00A411D0>
py> print special_file
<__main__.myFile object at 0x00A3D1D0>
py> print dir(regular_file)
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__',
'__getattribute
__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__',
'__reduce_ex__
', '__repr__', '__setattr__', '__str__', 'close', 'closed', 'encoding',
'fileno'
, 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read',
'readinto', 're
adline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write',
'writeli
nes', 'xreadlines']
py> print dir(special_file)
['__class__', '__delattr__', '__doc__', '__getattr__', '__getattribute__',
'__ha
sh__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
'__re
pr__', '__setattr__', '__slots__', '__str__', '_file', 'mymethod']
py> with special_file:
... special_file.write("hello\n")
... special_file.mymethod()
...
anything
py> print "closed?", special_file.closed
closed? True
</output>

(note that __enter__/__exit__ -used by the with statement- work fine, even
if not listed by dir(); also the "closed" attribute exists and is set
correctly)

Note also that myFile is *not* a subclass of file:

py> isinstance(special_file, file)
False

but it has all methods and attributes of file objects, even if
dir(special_files) doesn't list them. Duck typing in action - typical
Python code should work fine with this myFile object instead of a true
file object, but if you actually need a file subclass, I think you'll have
to write a C extension.

--
Gabriel Genellina

0 new messages