Overriding "__setattr__" of a module - possible?
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Fri Jun 18 00:25:04 EDT 2010
En Thu, 17 Jun 2010 07:12:23 -0300, Fuzzyman <fuzzyman at gmail.com> escribió:
> On Jun 17, 10:29 am, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
> wrote:
>> En Thu, 17 Jun 2010 04:52:48 -0300, Alf P. Steinbach <al... at start.no>
>> escribió:
>>
>> > But who would have thunk that Python *isn't dynamic enough*? :-)
>>
>> Yep... There are other examples too (e.g. the print statement in 2.x
>> bypasses sys.stdout.write;
>
> What do you mean by this? The print statement in 2.x does *not* bypass
> sys.stdout. It may use other methods besides write (writeln perhaps)
> but you can *definitely* override sys.stdout to capture the output
> from print statements.
Suppose you want to implement a "tee" variant in Python: print output
should go to stdout and also to some file (with timestamp added, just to
be fancy). First attempt:
py> import sys
py> import time
py>
py> class tee(file):
... def write(self, data):
... file.write(self, '%s: %r\n' % (time.ctime(), data))
... sys.__stdout__.write(data)
...
py> sys.stdout = tee('test.txt', 'w')
py> print "Hello world"
py> print "Bye"
py> ^Z
D:\TEMP>type test.txt
Hello world
Bye
Note:
- no output to stdout inside the interpreter
- no timestamp in the file
This modified version works fine:
py> class tee():
... def __init__(self, filename, mode):
... self.file = open(filename, mode)
... def write(self, data):
... self.file.write('%s: %r\n' % (time.ctime(), data))
... sys.__stdout__.write(data)
What happened? When sys.stdout is an instance of some class inheriting
from file (that is, isinstance(sys.stdout, file) is true) then the print
statement ignores sys.stdout.write() completely -- instead it calls
directly some C stdio functions (fwrite).
The only way to influence 'print' is *not* to inherit from file in the
first place.
It's an optimization, sure. I guess it is there before inheriting from
builtin types was allowed (in such scenario, it's a perfectly valid
optimization). Now, perhaps the test for 'file' should be more strict,
only taking the C shortcut when using an actual file instance, not a
subclass of it. This would allow the example above to work correctly.
--
Gabriel Genellina
More information about the Python-list
mailing list