PythonScope
ThoughtStorms Wiki
Context: PythonLanguage
print("""
Scope demo in Python
the x bound in the scope of f is visible within y
but is not the same as the x bound at the global scope
x = 4 y = 3 def f(x) : def g(y) : print("in g, x is %s" % x) print("in g, y is %s" % y) return x * y print("in f, x is %s" % x) return g
print("global x is %s, y is %s"%(x,y)) print("calculating .... the result is %s "% f(5)(6)) print("global x is %s, y is %s"%(x,y))
>> """)
x = 4 y = 3 def f(x) : def g(y) : print("in g, x is %s" % x) print("in g, y is %s" % y) return x * y print("in f, x is %s" % x) return g
print("global x is %s, y is %s"%(x,y)) print("calculating .... the result is %s "% f(5)(6)) print("global x is %s, y is %s"%(x,y))
print("""
what you can't do in python is assign to the captured variable x inside function g
that will give an error
there isn't an explicit "upvar" but as a workaround you can use global,
but that means something different, and makes you work with global vars,
which isn't ideal
So it's best to treat variables captured in closures as immutable
which is actually a good thing anyway, because updating them
can lead to a world of confusion and pain
If you REALLY want mutable variables in a context which can be passed around
It's better to just use a class and do things the Object Oriented way
which is more explicit and easy for people to understand
class F : def init(self,x) : self.x = x print("in F, x is %s" % self.x)
def updateX(self,x) : self.x = x print("in F, x is now %s" % self.x) return self def calcWithY(self,y) : print("in calc, x is %s" % self.x) print("in calc, y is %s" % y) return self.x * y
print("oo result is %s " % F(9).updateX(5).calcWithY(6)) print("global x is %s, y is %s"%(x,y))
>> """)
class F : def init(self,x) : self.x = x print("in F, x is %s" % self.x)
def updateX(self,x) : self.x = x print("in F, x is now %s" % self.x) return self def calcWithY(self,y) : print("in calc, x is %s" % self.x) print("in calc, y is %s" % y) return self.x * y
print("oo result is %s " % F(9).updateX(5).calcWithY(6)) print("global x is %s, y is %s"%(x,y))
print("""
Python makes a good trade-off here, I think
Closures are more concise and arguably more expressive
But less explicit and so somewhat harder to understand
Immutability makes things easier to understand
So immutable captured variables in closures buys
ease of understanding at the cost of reduced power
And if you really need mutability, python forces you to use OO
Which makes things more explicit and familiar
particularly because of Python's self notation
You can't confuse self.x with any x's that are floating around the global namespace
""")
No Backlinks