Python Forum
will with sys.stdout as f: close sys.stdout?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
will with sys.stdout as f: close sys.stdout?
#1
i have a big block of code the i do not want to duplicate. in one case i want the block to be done with f as an opened file that gets closed at the end. in the other case it should output to stdout without closing stdout. at first i did it like this:
    for name in all_the_names:
        with stdout if 'stdout' in options else open(f'{name}.log','w') as f:
            ...
            print(...,file=f) # many lines of code here, do not copy
            ...
then i realized that the with might cause stdout to be closed. would that really happen? if so, how can i avoid that?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
A contextmanager should do the trick (to be tested)
from contextlib import contextmanager
import sys

@contextmanager
def outfile(name, use_stdout):
    if use_stdout:
        yield sys.stdout
    else:
        with open(f'{name}.log', 'w') as f:
            yield f

for name in all_the_names:
    with outfile(name, stdout in options) as f:
        print('Spam', file=f)
Reply
#3
could that work for this other thing i want do? i want to be able to open and write a file with a temporary name of my choice and when with closes it, it also gets renamed to the permanent name.
for name in names:
    t = int(time.time()*3906250)
    with tmpopen(f'{name}-(t)',name,'w') as f
        print('#!/usr/bin/env python3',file=f)
        print('# put your code here:',file=f)
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
Skaperen Wrote:could that work for this other thing i want do?
Of course it would, you only need to rename the file after the 'with open...' block in the contextmanager. But I think we already discussed this problem in the forum and we wrote a solution somewhere.
Reply
#5
i want to do it within the with statement so that it is sure to happen (or at least be attempted). sure, i can do it after the with. i can close the file after the with, too. the justification for using with to do a close ... i want to use for doing the rename, too. so i would expect a method that returns an object with a context manager that takes care of both the close and the rename.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#6
It is after the with statement in the context manager but it is included in the with statement for the code that uses the contextmanager.
Reply
#7
i thought with called some special method on the file(-like) object used in the with statement that does a close on the file.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#8
Skaperen Wrote:i thought with called some special method on the file(-like) object used in the with statement that does a close on the file.

In the statement
with foo as bar:
    spam()
bar is not foo, it is the value returned by foo.__enter__() which can be anything, including a file object. At the end of the with statement's execution, no method is called on bar, but the method foo.__exit__() is called.

It often happens that foo and bar are the same object, for example when foo is the result of a call to open(). The __exit__() method on a file object calls the close() method, but in general you can program whatever behaviour at a block's exit, even if bar is a file object.
Reply
#9
The use of a context manager together with sys.stdout does not make much sense, because the fd is open until the program ends.

import os


with os.fdopen(sys.stdout.fileno(), 'w', closefd=False) as fd:
    fd.write('Hello World\n')

# is still open
sys.stdout.write('Hello World\n')
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#10
It makes sense here because Skaperen wants the same client code whether he uses stdout or a regular file. It's an API normalization.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [subprocess] Why stdout sent to stderr? Winfried 3 461 Jan-26-2024, 07:26 PM
Last Post: snippsat
  Performance options for sys.stdout.writelines dgrunwal 11 3,098 Aug-23-2022, 10:32 PM
Last Post: Pedroski55
  Controlling what get outputted to stdout when running external commands Daring_T 4 2,150 Jan-30-2022, 05:40 PM
Last Post: bowlofred
  Did subprocess.Popen() causes main routine to pause stdout? liudr 4 3,614 May-04-2021, 08:58 PM
Last Post: liudr
  changing stdout and stderr Skaperen 4 2,680 Dec-02-2020, 08:58 PM
Last Post: Skaperen
  Get stdout of a running process yok0 0 3,010 Aug-20-2020, 10:12 AM
Last Post: yok0
  Add stdout to text file maxtimbo 3 3,145 Feb-05-2019, 12:53 AM
Last Post: maxtimbo
  Guizero HX711 Load Cell and python3 stdout? Tesla 1 3,725 Jan-16-2019, 01:15 PM
Last Post: Larz60+
  stdout buffering Skaperen 5 4,706 Jun-12-2018, 06:14 AM
Last Post: Skaperen
  stdout Skaperen 0 2,628 Mar-19-2018, 01:23 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020