Why is Python not supporting full derivation of built-in file class?
Pierre Rouleau
prouleau at impathnetworks.com
Sat Apr 23 17:30:52 EDT 2005
Greetings,
I'm wondering why the >> operator does not use the write() method of a
class derived from the built-in file class as in DerivedFile below.
In the following example:
- StringFile is just a file-like string accumulation class that can be
used in place of a real file to accumulate strings that would otherwise
be printed. Works fine, can accumulate strings with the >> operator,
but is not a true file.
- DelegatedFile is a new-style class, a true file class, which provides
all the features of a real file through delegation. It also works fine
and can accumulate string with the >> operator.
- DerivedFile is a new-style class that is derived from file. It
behaves like a true file, but the >> operator does not call its write()
method. Why is that?
Is this related to the fact that on object from that class is seen as a
file (as shown at the end of the code session below)?
Is this intended or is it a flaw in the language that is waiting to be
fixed?
>>> import sys
>>> sys.ps2=' ... '; sys.ps1=' >>> '
>>> def hello(stream=None):
... if stream is None:
... stream = sys.stdout
... print >> stream, "Bonjour!"
...
>>> # Using a duck-typing to define a class
... # that behaves like a file for writing only.
... class StringFile:
... "A file-like object to accumulate strings"
... # print >> aStringFile works
... def __init__(self):
... self.strings = []
... def write(self, text):
... self.strings.append(text)
... def writelines(self, lines):
... self.strings.extend(lines)
...
>>> # Using delegation to file to create a class that
... # extends the built-in file object.
... class DelegatedFile(object):
... "A file-like object to accumulate strings"
... # print >> aStringFile works
... def __init__(self, *args):
... self.strings = []
... self._file = file(*args)
... def __getattr__(self, name) :
... return getattr(self._file, name)
... def write(self, text):
... self.strings.append(text)
... self._file.write(text)
... def writelines(self, lines):
... self.strings.extend(lines)
... self._file.writelines(lines)
...
>>> # Using derivation from file to create a class
... # that extends file. But has a flaw in the use of the >> operator!
... class DerivedFile(file):
... "A file object that accumulated written strings"
... # print >> a DerivedFile doe NOT work!
... def __init__(self, *args):
... self.strings = []
... file.__init__(self, *args)
... def write(self, text):
... self.strings.append(text)
... file.write(self, text)
... # super(DerivedFile, self).write(text)
... def writelines(self, lines):
... self.strings.extend(lines)
... file.writelines(self, lines)
... # super(DerivedFile, self).writelines(lines)
...
>>> hello()
Bonjour!
>>>
>>> sf = StringFile()
>>> hello(sf)
>>> sf.strings
['Bonjour!', '\n']
>>>
>>> dg = DelegatedFile("temp.txt","w")
>>> hello(dg)
>>> dg.close()
>>> dg.strings
['Bonjour!', '\n']
>>> for line in file("temp.txt"): print line
...
Bonjour!
>>> df = DerivedFile("temp2.txt","w")
>>> hello(df)
>>> df.close()
>>> df.strings
[]
>>> for line in file("temp2.txt"): print line
...
Bonjour!
>>>
>>> sf
<__main__.StringFile instance at 0x008D86C0>
>>> dg
<__main__.DelegatedFile object at 0x008D50B0>
>>> df
<closed file 'temp2.txt', mode 'w' at 0x0087FA28>
>>>
--
Pierre Rouleau
More information about the Python-list
mailing list