DEV Community

Discussion on: How would you rewrite this Python code?

Collapse
 
rhymes profile image
rhymes • Edited

I think the simplest is the first one :D

Or you can wrap that if in a normal function if you plan to use it more than once:

def file_or_stdout(fname=None):
  if fname:
    return open(fname, 'w')
  else:
    return sys.stdout

I don't think you need to use a context manager in this case because there are no other operations between the opening and closing of the file.

Anyway I wouldn't do it like that.

Keep in mind that if you use sys.stdout this way you will close it which means that any attempt to write on it after your with statement will result in an error:

>>> import sys
>>> with file_or_stdout() as f:
...     f.write("Yo!\n")
...
Yo!
4
>>> sys.stdout.write("Yo 2\n")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.
>>> print("yo 3")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.

So why do you need to hide stdout this way? It's probably easier to use StringIO, write to it and then use a print to display it on stdout.

Collapse
 
cathodion profile image
Dustin King

So why do you need to hide stdout this way?

I'm just trying to keep the code clear and non-repetitive. In terms of level of effort and maintainability, if it needs to be able to optionally write to a file, breaking the inner logic out into a function as inspired by @thinkslynk is probably best.

But if it's a one-off project it might be even better to only write to stdout and pipe it to a file in the shell if needed. (Sometimes it's fun to over-engineer though.)

Collapse
 
tadaboody profile image
Tomer

Actually the context manager solves this by only opening/closing the fp if it isn't to stdout so it might be the best solution

Collapse
 
rhymes profile image
rhymes

Oh yes, you're right :-)

+1 to the context manager, though it might be overkill if the function is used only once.