82

I am reading only firstline from python using :

with open(file_path, 'r') as f:
    my_count = f.readline()
print(my_count)

I am bit confused over scope of variable my_count. Although prints work fine, would it be better to do something like my_count = 0 outside with statement first (for eg in C in used to do int my_count = 0)

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
danish sodhi
  • 1,793
  • 4
  • 21
  • 31

2 Answers2

132

A with statement does not create a scope (like if, for and while do not create a scope either).

As a result, Python will analyze the code and see that you made an assignment in the with statement, and thus that will make the variable local (to the real scope).

In Python variables do not need initialization in all code paths: as a programmer, you are responsible to make sure that a variable is assigned before it is used. This can result in shorter code: say for instance you know for sure that a list contains at least one element, then you can assign in a for loop. In Java assignment in a for loop is not considered safe (since it is possible that the body of the loop is never executed).

Initialization before the with scope can be safer in the sense that after the with statement we can safely assume that the variable exists. If on the other hand the variable should be assigned in the with statement, not initializing it before the with statement actually results in an additional check: Python will error if somehow the assignment was skipped in the with statement.

A with statement is only used for context management purposes. It forces (by syntax) that the context you open in the with is closed at the end of the indentation.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • So Do I need initialization ? Or I can use variable my_count outside the with statement like I am doing. What would be better practice ? – danish sodhi Jul 14 '17 at 10:15
  • 1
    @crystal: I updated the answer with more information about that. Does this answers your question? – Willem Van Onsem Jul 14 '17 at 10:26
  • Thanks for the explanation :D – danish sodhi Jul 14 '17 at 10:58
  • It feels really un-Pythonic though. I try to avoid using variables initialized in a for loop later, and variables I assign in an if-block always have a similar assignment in an else-block. Similar with try/except blocks. While such a safe-guard would not be necessary for with-statements, it just looks /wrong/ somehow. Assignments in if-statements also feel a little bad, so I prefer conditional expressions. Unfortunately with-statements don't seem to have something similar.. – BlackShift Sep 27 '17 at 08:06
  • 1
    @BlackShift: yes but for `with` statements, it is another case. Since the body is executed (until an exception or the end). It is sometimes good to make a `with` statement as short as possible, since it for instance opens a file, and we want to close the file as soon as possible. – Willem Van Onsem Sep 27 '17 at 08:12
  • 1
    @Willem Van Onsem, Yeah, I really have to train myself to make my with-blocks short. What usually happens is that I 1) write a function with a with-statement (mostly opening a file), 2) automatically put everything that (indirectly) uses the 'as' variable in the block, including any return-statement, 3) realize that return statements should (normally) not be in a block, 4) unindent almost everything again (usually only except 'read'), 5) feel bad because the code doesn't look nice to my eyes :-). But well. – BlackShift Sep 27 '17 at 08:27
7

You should also go through PEP-343 and Python Documentation. It will clear that its not about creating scope its about using Context Manager. I am quoting python documentation on context manager

A context manager is an object that defines the runtime context to be established when executing a with statement. The context manager handles the entry into, and the exit from, the desired runtime context for the execution of the block of code. Context managers are normally invoked using the with statement (described in section The with statement), but can also be used by directly invoking their methods.

Typical uses of context managers include saving and restoring various kinds of global state, locking and unlocking resources, closing opened files, etc.

Community
  • 1
  • 1
pyvkd
  • 96
  • 5