Variable Defined with With-Statement Available Outside of With-Block

Variable defined with with-statement available outside of with-block?

Yes, the context manager will be available outside the with statement and that is not implementation or version dependent. with statements do not create a new execution scope.

using python variable outside with statement

Variable scope only applies at the function, module, and class levels. If you are in the same function/module/class, all variables defined will be available within that function/module/class, regardless of whether it was defined within a with, for, if, etc. block.

For example, this:

for x in range(1):
y = 1
print(y)

is just as valid (although pointless) as your example using the with statement.

However, you must be careful since the variable defined within your code block might not actually be defined if the block is never entered, as in this case:

try:
with open('filedoesnotexist', 'r') as file:
pass
except:
pass # just to emphasize point

print(file.mode)

Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
file.mode
NameError: name 'file' is not defined

Good description of LEGB rule of thumb for variable scope

Scope of variable within with statement?

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.

Is a variable defined in with open as block available for the code in outer block?

Yes, in Python, variable scope extends outside of blocks (with the exception of function and class blocks). This means you can do stuff like:

if True:
a = 1

a += 1
print(a) # 2

The same principle applies for with blocks:

with open('data.txt') as file:
data = file.read()

print(data)

Note that if an exception is raised, the variable isn't assigned (but in your case, you already handle this with ktext = "" in the except-block).

python - Variable scope after using a 'with' statement

Yes, in Python the scope of a variable ends only when the code block it's defined in ends, and the with statement is not a code block per the documentation:

The following are blocks: a module, a function body, and a class
definition. Each command typed interactively is a block. A script file
(a file given as standard input to the interpreter or specified as a
command line argument to the interpreter) is a code block. A script
command (a command specified on the interpreter command line with the
‘-c’ option) is a code block. The string argument passed to the
built-in functions eval() and exec() is a code block.

Scope of variable in Python with statement

Python variables stay within scope until the end of the method. There are no 'blocks' for scope in python

Why is __del__ called at the end of a with block?

It's important to note that foo is not an object of type Foo. You do create a Foo and need to keep it around because it might contain state information needed to call __exit__. But once that's done, the object is unneeded and Python's free to throw it away.

Put another way, this:

with Foo() as foo:
print ('Hello World!')

Is the same as this:

_bar = Foo()
foo = _bar.__enter__()
print ('Hello World!')
_bar.__exit__()
del _bar # This will call __del__ because _bar is the only reference

The behavior you are expecting would happen if foo were a reference to the with block's foo. For example...

class Foo:
def __init__(self):
print ("__int__() called.")

def __del__(self):
print ("__del__() called.")

def __enter__(self):
print ("__enter__() called.")
return self # foo now stores the Foo() object

def __str__(self):
return 'returned_test_str'

def __exit__(self, exc, value, tb):
print ("__exit__() called.")

def close(self):
print ("close() called.")

def test(self):
print ("test() called.")

if __name__ == "__main__":
with Foo() as foo:
print ("with block begin???")
print ("with block end???")

print ("foo:", foo) # line 1

Prints

__int__() called.
__enter__() called.
with block begin???
with block end???
__exit__() called.
foo: returned_test_str
__del__() called.

I have no idea why Connection.__exit__ would leave its cursors open however.

Variable defined with with-statement available outside of with-block?

Yes, the context manager will be available outside the with statement and that is not implementation or version dependent. with statements do not create a new execution scope.



Related Topics



Leave a reply



Submit