473,503 Members | 12,003 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

print doesn't respect file inheritance?

I was trying to change the behaviour of print (tee all output to a
temp file) by inheriting from file and overwriting sys.stdout, but it
looks like print uses C-level stuff to do its writes which bypasses
the python object/inhertiance system. It looks like I need to use
composition instead of inheritance, but thought this was strange
enough to note.

$python -V
Python 2.5

"""A short demo script"""
class notafile(file):
def __init__(self, *args, **kwargs):
readonly = ['closed', '__class__', 'encoding', 'mode', 'name',
'newlines', 'softspace']
file.__init__(self, *args, **kwargs)
for attr in dir(file):
if attr in readonly: continue
setattr(self, attr, None)
def main():
n = notafile('/dev/stdout', "w")
print vars(n)

import sys
sys.stdout = n
print "Testing: 1, 2, 3..."
output:
{'__str__': None, 'xreadlines': None, 'readlines': None, 'flush':
None, 'close': None, 'seek': None, '__init__': None, '__setattr__':
None, '__reduce_ex__': None, '__new__': None, 'readinto': None,
'next': None, 'write': None, '__doc__': None, 'isatty': None,
'truncate': None, 'read': None, '__reduce__': None,
'__getattribute__': None, '__iter__': None, 'readline': None,
'fileno': None, 'writelines': None, 'tell': None, '__delattr__': None,
'__repr__': None, '__hash__': None}
Testing: 1, 2, 3...
Jul 26 '08 #1
7 1401
bukzor <wo**********@gmail.comwrites:
I was trying to change the behaviour of print (tee all output to a
temp file) by inheriting from file and overwriting sys.stdout
That's not what your code does, though.
def main():
n = notafile('/dev/stdout', "w")
Creates a new instance of the 'notafile' class; the '=' operator then
binds that instance to the name 'n'.
import sys
Imports a module, and binds the module to the name 'sys'. This
includes, usually, the module attribute named by 'sys.stdout'.
sys.stdout = n
Re-binds the name 'sys.stdout' to the object already referenced by the
name 'n'. No objects are changed by this; only bindings of names to
objects.
print "Testing: 1, 2, 3..."
Doesn't rely at all on the name 'sys.stdout', so isn't affected by all
the binding of names above.
In other words, you can't change the object used by the 'print'
statement only by re-binding names (which is *all* that is done by the
'=' operator).

You can, however, specify which file 'print' should use
<URL:http://www.python.org/doc/ref/print.html>.

--
\ “When I wake up in the morning, I just can't get started until |
`\ I've had that first, piping hot pot of coffee. Oh, I've tried |
_o__) other enemas...” —Emo Philips |
Ben Finney
Jul 26 '08 #2


bukzor wrote:
I was trying to change the behaviour of print (tee all output to a
temp file) by inheriting from file and overwriting sys.stdout, but it
looks like print uses C-level stuff to do its writes which bypasses
the python object/inhertiance system. It looks like I need to use
composition instead of inheritance, but thought this was strange
enough to note.

$python -V
Python 2.5

"""A short demo script"""
class notafile(file):
def __init__(self, *args, **kwargs):
readonly = ['closed', '__class__', 'encoding', 'mode', 'name',
'newlines', 'softspace']
file.__init__(self, *args, **kwargs)
for attr in dir(file):
if attr in readonly: continue
setattr(self, attr, None)
Drop the __init__ and give notafile a .write method.
Composition version inheritance is not the the real issue.
>>class nf(object):
def write(s):
print(s)
print(s)
>>print >>nf(), 'testing'
testing
testing

Now change nf.write to put the copy where you want it.

tjr

Jul 26 '08 #3
On Sat, 26 Jul 2008 14:07:52 +1000
Ben Finney <bi****************@benfinney.id.auwrote:
sys.stdout = n

Re-binds the name 'sys.stdout' to the object already referenced by the
name 'n'. No objects are changed by this; only bindings of names to
objects.
I do agree that the object formerly known as sys.stdout hasn't changed.
print "Testing: 1, 2, 3..."

Doesn't rely at all on the name 'sys.stdout', so isn't affected by all
the binding of names above.
Hmm. Are you saying that the following doesn't work?

$ python
>>f = open("test", "w")
import sys
sys.stdout = f
print "test message"
sys.exit(0)
$ cat test
test message
In other words, you can't change the object used by the 'print'
statement only by re-binding names (which is *all* that is done by the
'=' operator).
Apparently I can.
You can, however, specify which file 'print' should use
<URL:http://www.python.org/doc/ref/print.html>.
Which contains this statement.

"Standard output is defined as the file object named stdout in the
built-in module sys."

I suppose that there might be some ambiguity there but the proof, as
they say, is in the pudding.

--
D'Arcy J.M. Cain <da***@druid.net | Democracy is three wolves
http://www.druid.net/darcy/ | and a sheep voting on
+1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.
Jul 26 '08 #4
Lie
On Jul 26, 8:50*am, bukzor <workithar...@gmail.comwrote:
I was trying to change the behaviour of print (tee all output to a
temp file) by inheriting from file and overwriting sys.stdout, but it
looks like print uses C-level stuff *to do its writes which bypasses
the python object/inhertiance system. It looks like I need to use
composition instead of inheritance, but thought this was strange
enough to note.

$python -V
Python 2.5

"""A short demo script"""
class notafile(file):
* * def __init__(self, *args, **kwargs):
* * * * readonly = ['closed', '__class__', 'encoding', 'mode', 'name',
'newlines', 'softspace']
* * * * file.__init__(self, *args, **kwargs)
* * * * for attr in dir(file):
* * * * * * if attr in readonly: continue
* * * * * * setattr(self, attr, None)

def main():
* * n = notafile('/dev/stdout', "w")
* * print vars(n)

* * import sys
* * sys.stdout = n
* * print "Testing: 1, 2, 3..."

output:
{'__str__': None, 'xreadlines': None, 'readlines': None, 'flush':
None, 'close': None, 'seek': None, '__init__': None, '__setattr__':
None, '__reduce_ex__': None, '__new__': None, 'readinto': None,
'next': None, 'write': None, '__doc__': None, 'isatty': None,
'truncate': None, 'read': None, '__reduce__': None,
'__getattribute__': None, '__iter__': None, 'readline': None,
'fileno': None, 'writelines': None, 'tell': None, '__delattr__': None,
'__repr__': None, '__hash__': None}
Testing: 1, 2, 3...
Use this:

class fakefile(object):
def __init__(self, writeto, transformer):
self.target = writeto
self.transform = transformer
def write(self, s):
s = self.transform(s)
self.target.write(s)
sys.stdout = fakefile(sys.stdout, lambda s: '"' + s + '"')

Inheriting from file is not the best way to do it since there is a
requirement that child class' interface must be compatible with the
parent class' interface, since the file-like object you're creating
must have extremely different interface than regular file, the best
way is to use Duck Typing, i.e. write a class that have .write()
method.
Jul 26 '08 #5
"D'Arcy J.M. Cain" <da***@druid.netwrites:
Hmm. Are you saying that the following doesn't work?

$ python
>f = open("test", "w")
import sys
sys.stdout = f
print "test message"
sys.exit(0)
$ cat test
test message
In other words, you can't change the object used by the 'print'
statement only by re-binding names (which is *all* that is done by
the '=' operator).

Apparently I can.
I admit to not trying any of the above. I was explaining the behaviour
reported by the original poster, without experimenting to see if I
could reproduce the behaviour.

Thanks for being more diligent.

--
\ “All persons, living and dead, are purely coincidental.” |
`\ —_Timequake_, Kurt Vonnegut |
_o__) |
Ben Finney
Jul 27 '08 #6
On Jul 26, 7:08*am, "D'Arcy J.M. Cain" <da...@druid.netwrote:
On Sat, 26 Jul 2008 14:07:52 +1000

Ben Finney <bignose+hates-s...@benfinney.id.auwrote:
* * sys.stdout = n
Re-binds the name 'sys.stdout' to the object already referenced by the
name 'n'. No objects are changed by this; only bindings of names to
objects.

I do agree that the object formerly known as sys.stdout hasn't changed.
* * print "Testing: 1, 2, 3..."
Doesn't rely at all on the name 'sys.stdout', so isn't affected by all
the binding of names above.

Hmm. *Are you saying that the following doesn't work?

$ python>>f = open("test", "w")
>import sys
sys.stdout = f
print "test message"
sys.exit(0)

$ cat test
test message
In other words, you can't change the object used by the 'print'
statement only by re-binding names (which is *all* that is done by the
'=' operator).

Apparently I can.
You can, however, specify which file 'print' should use
<URL:http://www.python.org/doc/ref/print.html>.

Which contains this statement.

"Standard output is defined as the file object named stdout in the
built-in module sys."

I suppose that there might be some ambiguity there but the proof, as
they say, is in the pudding.

--
D'Arcy J.M. Cain <da...@druid.net* * * * | *Democracy is three wolveshttp://www.druid.net/darcy/* * * * * * * *| *and a sheep voting on
+1 416 425 1212 * * (DoD#0082) * *(eNTP) * | *what's for dinner.
Thanks for backing me up.

Nobody here thinks it's strange that print uses *none* of the
attributes or methods of sys.stdout to do its job? The implementation
seems to bypass the whole python system and use C-level FILE* pointers
directly instead.
Jul 28 '08 #7
bukzor wrote:
I was trying to change the behaviour of print (tee all output to a
temp file) by inheriting from file and overwriting sys.stdout, but it
looks like print uses C-level stuff to do its writes which bypasses
the python object/inhertiance system. It looks like I need to use
composition instead of inheritance, but thought this was strange
enough to note.

$python -V
Python 2.5

"""A short demo script"""
class notafile(file):
def __init__(self, *args, **kwargs):
readonly = ['closed', '__class__', 'encoding', 'mode', 'name',
'newlines', 'softspace']
file.__init__(self, *args, **kwargs)
for attr in dir(file):
if attr in readonly: continue
setattr(self, attr, None)
def main():
n = notafile('/dev/stdout', "w")
print vars(n)

import sys
sys.stdout = n
print "Testing: 1, 2, 3..."
output:
{'__str__': None, 'xreadlines': None, 'readlines': None, 'flush':
None, 'close': None, 'seek': None, '__init__': None, '__setattr__':
None, '__reduce_ex__': None, '__new__': None, 'readinto': None,
'next': None, 'write': None, '__doc__': None, 'isatty': None,
'truncate': None, 'read': None, '__reduce__': None,
'__getattribute__': None, '__iter__': None, 'readline': None,
'fileno': None, 'writelines': None, 'tell': None, '__delattr__': None,
'__repr__': None, '__hash__': None}
Testing: 1, 2, 3...
I tried the code (on Windows, so had to change /dev/stdout to
/temp/notafile.txt) and it worked just fine. Perhaps the issue is that
n is being set to /dev/stdout instead of some other file so no
difference is apparent?

In other words, you're assigning stdout to stdout.

~Ethan~
Sep 5 '08 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
2198
by: Andrew Chalk | last post by:
In a Python 2.2 app. running under CGI the statements print "Hello\n" print "World" print both words on the same line in IE6. How do I print the second one on a new line (i.e. respect the \n...
14
2882
by: Marcin Ciura | last post by:
Here is a pre-PEP about print that I wrote recently. Please let me know what is the community's opinion on it. Cheers, Marcin PEP: XXX Title: Print Without Intervening Space Version:...
7
3679
by: gino | last post by:
Dear all, My monitor was set to 1600x1200 so the fonts in IE is too small for me even when I set the "View->Text Size->Largest"... I don't have previlage to change the monitor resolution... ...
13
2866
by: cefrancke | last post by:
I have a custom toolbar for users during any preview of a report launched by a button click on a form. I would like to add a toolbar button to launch the Print Dialog (like 'Ctrl-P' or...
5
1867
by: Paul Sullivan | last post by:
We are a state agency that views protected medical information via our intranet. The screens even have privacy shields. Alarmingly, uses can "Print" and "Save As" which destroys the protection of...
1
5682
by: hamil | last post by:
I am trying to print a graphic file (tif) and also use the PrintPreview control, the PageSetup control, and the Print dialog control. The code attached is a concatination of two examples taken out...
9
5184
by: Myombi Natuse | last post by:
I need to print a bitmap file in C under Windows. I'm a senior in college so please show me the respect I'm due. I don't want any of you jokers telling me that it can't be done because I know it...
4
2936
by: carl.dhalluin | last post by:
Hello I am completely puzzled why the following exec code does not work: mycode = "import math\ndef f(y):\n print math.floor(y)\nf(3.14)" def execute(): exec mycode execute()
3
1174
by: iu2 | last post by:
Hi, I'm trying to write data to both a file and the console, so I did: class File_and_console(file): def write(self, s): file.write(self, s) print s, hello
0
7264
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7316
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6975
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
4992
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4666
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3160
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1495
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
728
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
371
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.