0

For example, I need to open two files using one with statement. And there's also a condition for each of them: to actually open or to use something instead.

In my case, it's whether to open a file specified by name or use stdin/stdout if name is not specified. The problem is that it's too long and complex for single line.

with    open(src_name, 'r') if src_name else sys.stdin as src, open(dst_name, 'w') if dst_name else sys.stdout as dst:
    # do something
    pass

For the first time, I had something like:

with    open(src_name, 'r') if src_name else sys.stdin as src, \
        open(dst_name, 'w') if dst_name else sys.stdout as dst:
    # do something
    pass

I personally like this version. For me it looks straightforward, but I need to use spaces to align two lines (and my IDE, PyCharm, warns me about extra spaces). BTW, Is it really critical to use spaces in python to align code?

The other way to align is:

with open(src_name, 'r') if src_name else sys.stdin as src, \
     open(dst_name, 'w') if dst_name else sys.stdout as dst:
    # do something
    pass

But it seems even worse due to PEP 8 – indentation.

And I don't like the "correct" version which is less readable and for the first glance even confusing:

with open(src_name, 'r') if src_name else sys.stdin as src, \
        open(dst_name, 'w') if dst_name else sys.stdout as dst:
    # do something
    pass

I can nest it in two levels but it is bad according to zen..

So i'm interested if there's a more elegant way to write this? Or maybe my version is good and I should ignore that warning about spaces.

Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
  • 2
    Please ask this question on https://codereview.stackexchange.com/ – smac89 Jan 21 '18 at 09:28
  • 1
    The premise of the question is (kind of) wrong - you never ever ever want to write `with sys.stdin:` or `with sys.stdout:`. You won't be able to use `input()` or `print()` after the `with` statement. – Aran-Fey Jan 21 '18 at 09:44
  • @Rawing oh, you pointed out an important problem in that code. I didn't think about closing the stdin/stdout and that's something to remember. Thank you, maybe you saved some hours of my life handling future errors due to that approach. – Ivan Bogush Jan 22 '18 at 10:28

1 Answers1

1

To quote the great uncle bob, author of 'Clean Code' and famed engineer, 'never let the readers of your code scroll sideways', and 'your code should read like well written prose'.

Instead of placing the if statement within the with block, why not separate them.

if src_name:
    with open(src_name, 'r') as f:
        pass #do something
else:
    pass # do something else

Also, consider using better names for your variables, i.e. instead of src_name use file_path > makes more sense.

I highly recommend 'Clean Code' by Robert C. Martin - it changed my life.

Eytan Avisror
  • 2,860
  • 19
  • 26
  • 1
    Now you get duplicated code. A function would work best – smac89 Jan 21 '18 at 09:34
  • Well, i'm not sure exactly what you are trying to do, but I was just trying to make a point about readability with my code snippet. – Eytan Avisror Jan 21 '18 at 09:34
  • You can also create a function that handles the boolean condition – Eytan Avisror Jan 21 '18 at 09:36
  • That's what I meant by "A function would work best". – smac89 Jan 21 '18 at 09:37
  • 1
    @EytanAvisror Thank you, I got your point. And what about my additional question "BTW, Is it really critical to use spaces in python to align code?". May be you read it in the book you recommended? – Ivan Bogush Jan 22 '18 at 10:24
  • It depends what you mean by spaces - Indentation is very critical in python. PEP8 is should be looked at as recommended style, many programmers chose to write in different styles - personally I adhere to PEP8, I think it looks great, and works well for code readability. – Eytan Avisror Jan 22 '18 at 11:51