when you code in many languages, you usually need to dig a bit to find answers to questions that are not immediately obvious in a specific language. Mine was whether closures can simulate real private variables in python (i.e that really can’t be accessed as opposed to the __ mangling method).
I decided to test if this would work with closures, as shown below
def outer(a,b):
class this:
pass
#--------------------------
# real private variables and methods go here
this.a = a
this.b = b
def sum_():
return this.a + this.b
def product_():
return this.a * this.b
def set_nums_(a, b):
this.a, this.b = a, b
#--------------------------
# public variables and methods go here
class inner:
def get_nums(self):
return this.a, this.b
def set_nums(self, a, b):
set_nums_(a,b)
def sum(self):
return sum_()
def product(self):
return product_()
return inner()
and the result:
>>> x = outer(5,3)
>>> x.get_nums()
(5, 3)
>>> x.set_nums(5,4)
>>> x.get_nums()
(5, 4)
>>> x.product()
20
>>> x
<__main__.outer..inner object at 0x0000023C581E21C0>
>>>
Yay! seems like it works.
Of course, a bit of further digging showed that every python object has the __closure_
_ property through which you can access the closure for that object, and changing the values of the “private” variables above (bypassing the set_nums method) just becomes a matter of:
>>> loophole = x.sum.__closure__[0].cell_contents.__closure__[0].cell_contents
>>> loophole
<class '__main__.outer.<locals>.this'>
>>> loophole.a = 8
>>> loophole.b = 9
>>> x.get_nums()
(8, 9)
>>>