Change the representation of a Python object
In Python, datatypes (e.g. int, float) represent value, but also have some built-in attributes / functions / etc:
In [1]: a = 1.2
In [2]: a
Out[2]: 1.2
In [3]: a.is_integer()
Out[3]: False
Is it possible to reproduce this behavior in Python e.g. define class:
class Scalar:
def __init__(self, value)
self.value = value
# other code ....
s = Scalar(1.2)
where I could s
recover 1.2 (instead of input s.value
) and do things such as a = s
→ a = 1.2
? The closest I can get from this behavior is adding something like:
def __getitem__(self, key=None):
return self.value
and using a = s[()]
, but it doesn't look very good.
source to share
where I could return s 1.2 (instead of typing s.value)
In the console? Then we implement the method __repr__
.
a = s → a = 1.2
To avoid using it a = s.value
, you can implement __call__
and call the object:
>>> class Scalar:
... def __init__(self, value):
... self.value = value
... def __repr__(self):
... return str(self.value)
... def __call__(self):
... return self.value
...
>>> s = Scalar(1.2)
>>> s
1.2
>>> a = s()
>>> a
1.2
Check out the documentation about the data model when emulating numeric types .
For example:
class Scalar:
def __init__(self, value):
self.value = value
def __repr__(self):
return str(self.value)
def __call__(self):
return self.value
def __add__(self, other):
return Scalar(self.value + other.value)
def __lt__(self, other):
return self.value < other.value
def ___le__(self, other):
return self.value <= other.value
def __eq__(self, other):
return self.value == other.value
def __ne__(self, other):
return self.value != other.value
def __gt__(self, other):
return self.value > other.value
def __ge__(self, other):
return self.value >= other.value
Can be used like this:
>>> s1 = Scalar(1.2)
>>> s2 = Scalar(2.1)
>>> s1 + s2
3.3
>>> s1 < s2
True
>>> s1 > s2
False
>>> s1 != s2
True
>>> s1 <= s2
True
>>> s1 >= s2
False
There is also __int__
and __float__
magical techniques that you can implement and use like this (this is more semantically correct):
>>> a = int(s)
>>> a = float(s)
source to share
As far as I know, this is not possible for your example a = s
. You will have to change the behavior of the operator =
, the assignment operator. The assignment operator doesn't really do anything for the object on the right, it just copies the reference to it (in the case of the object, at least).
In general, it is possible to change the behavior of built-in operators for your custom classes using operator overloading , but Python does not provide this type of option for assignment ( =
) because of how different it is from operators such as addition ( +
) and even equality ( ==
).
source to share