-1

I am new to python and suddenly was surprised seeing that a variable is still visible outside the block in which it's declared and assigned. The code is below:

with open('data.txt', 'r') as file:
    text = file.readlines()
    # and when do I close the file?

for i in range(len(text)):  # still can access the text even after the block.
    print(text[i])

How is this possible for the variable to be seen from outside the block? Thanks in advance.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • 1
    Why shouldn't it be accessible? The context manager closes the file, but would you be surprised if some variable defined in an `if` block was accessible outside of it? – roganjosh Jan 13 '19 at 13:40
  • The variable is declared when it enters that block and is accessible outside. There is no need to close the file while using 'with open() as file'. – sk_462 Jan 13 '19 at 13:41
  • Python doesn't really have blocks. It certainly doesn't have block *scope*. The only scoping unit in Python is the named function (and `exec` (i.e. string eval) for some reason). – melpomene Jan 13 '19 at 13:41
  • Python doesn't have variable declarations. What you have in your `with` block is simple assignment. – melpomene Jan 13 '19 at 13:42
  • roganjosh and sk_353 much appreciated. it answer my question. – Abusayeed Roni Jan 13 '19 at 13:52
  • 1
    @roganjosh Many languages including C enforce block scoping. If you came from a C background, you would be very surprised to see this work. – Michael Jan 13 '19 at 13:59
  • @Michael fair observation :) Also, a perfectly legitimate response for the OP to have made for my question; it was not intended to show them up. It's ultimately my knowledge limitation on block scoping. – roganjosh Jan 13 '19 at 14:03
  • @Michael C has variable declarations, though. Simply assigning to a variable in a block doesn't limit its scope in C either. – melpomene Jan 13 '19 at 14:05
  • @roganjosh not a shot at you, I assumed you came from a python heavy background :) – Michael Jan 13 '19 at 14:06
  • @Michael you assumed correctly :) I also didn't take it as a shot at me, just wanted to clarify my initial question to the OP. I'm not the downvoter and always curious to understand the logic of the OP if it mismatches my own – roganjosh Jan 13 '19 at 14:08
  • @melpomene If you declare the variable inside the block its scope will be limited to the block `if (condition) { int i = 5; } if (i == 5) { /*stuff*/} // 'i' undeclared` versus `int i; if (condition) { i = 5; } if (i == 5) { /*stuff*/} // all good` (Apologies for the messiness, comments are limiting) – Michael Jan 13 '19 at 14:10

1 Answers1

1

Python doesn't have block scoping, it has function scoping for clarity but it doesn't enforce any scoping within a function.

With blocks implicitly call __enter__ and __exit__ methods and will close the file when you leave them, but in this case you're accessing the text variable which contains a list of lines not the file.

The real issue with code like this occurs if the block isn't entered and you reference a variable that doesn't exist yet.

x = False
if x:
    y = True
if y:   # NameError: name 'y' is not defined
    print ('yay')

versus

x = False
y = False
if x:
    y = True
if y:   # all good
    print ('yay')
Michael
  • 810
  • 6
  • 18