I was looking at the answer to this question: Is it possible to define a class constant inside an Enum?
What interested me most was the Constant class in Ethan Furman's answer.
class Constant:
def __init__(self, value):
self.value = value
def __get__(self, *args):
return self.value
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, self.value)
The question was about Python 3.4 but I'm using 2.7. In the answer Ethan sets the gravitational constant as an instance variable of the class Planet like so:
G = Constant(6.67300E-11)
My testing of this class in 2.7 shows that typing just G gives me this:
Out[49]: Constant(3)
(I set it to 3 for ease of use while testing. This looks like the __repr__
output to me, please correct me if I"m wrong.)
The value is available via G.value. However, in Ethan's answer he uses
return self.G * self.mass / (self.radius * self.radius)
This obviously only works if the value is returned vs the __repr__
output. Now if I change class Constant:
to class Constant(int):
then type G I still get the __repr__
output but if I type G * 4
I get 12
not the error I was getting. (TypeError: unsupported operand type(s) for *: 'instance' and 'int'
)
So clearly something like the int object can output a number when called. Is there a magic method I'm missing that would allow me to do this for the Constant class? Since constants could be strings, integers, or floats I'd prefer to have 1 class that handles them all vs 3 separate classes that extend those objects.
The value is also settable via G.value. Can I lock this down so the Constant class behaves likes an actual constant? (I suspect the answer is no.)