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
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to