Question about math.pi is mutable
Steven D'Aprano
steve at pearwood.info
Fri Nov 6 21:00:31 EST 2015
On Sat, 7 Nov 2015 09:19 am, Thomas 'PointedEars' Lahn wrote:
> It is certainly possible for attributes of (instances of) new-style
> classes (starting with Python 3.2 at the latest) to be read-only by
> declaring them a property that does not have a setter, or one that has a
> setter that throws a specific exception (here: the former):
>
> #--------------------------
> class SafeMath(object):
> def __init__ (self):
> from math import pi
> self._pi = pi
>
> @property
> def pi (self):
> return self._pi
The obvious problem with that is that it is trivially easy for the coder to
set self._pi to change the value of self.pi.
Here's a version that at first seems promising:
py> def builder():
... from math import pi as PI
... def pi(self):
... return PI
... return pi
...
py> class MathLib(object):
... pi = property(builder())
...
py> mathlib = MathLib()
py> mathlib.pi
3.141592653589793
py> mathlib.pi = 3.12
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
There's no _pi accessible that somebody might change. If you dig into the
property object itself, you eventually get to the cell object containing
the value for pi:
py> MathLib.pi.fget.__closure__[0]
<cell at 0xb7bd5134: float object at 0xb7be5c30>
but there doesn't appear to be any way to manipulate the cell internals to
change the value. But you don't need to:
py> MathLib.pi = property(lambda self: 4.2)
py> mathlib.pi
4.2
A determined coder can change nearly anything done in pure Python code.
*Personally*, I too would like Python to have some equivalent of (say)
Pascal `const`, names which cannot be rebound once assigned to the first
time. Not to prevent determined coders from changing things, but to avoid
*accidental* changes done in error.
--
Steven
More information about the Python-list
mailing list