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.

+3


source to share


2 answers


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)

      

+4


source


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 ( ==

).

+1


source







All Articles