Question

EDIT:

As mentioned in the responses, search keyword for this question is "assignment operator overloading in python".

I want to construct a class which will behave like an integer or string class behaves. Something like that:

x = "hello"
x.upper() # says "HELLO"


y = MyClass()
y = 3
y = 5
print(y) # will print 5
y.previous_value() # will yield 3

How can I build a class that behaves like this?

Edit:

The closest hack is this for now: https://stackoverflow.com/a/6012807/1952991

Was it helpful?

Solution

You can't achieve this:

y = MyClass()
y = 3
y = 5
y.previous_value() # will yield 3

Assignment in Python rebinds the name to another object. When you do y = 3, y is now a name for the integer 3, not for an instance of MyClass. This behaviour doesn't depend on the old RHS at all, and can't be intercepted by it without deep magic (you could possibly do something with context managers). The instance of MyClass that y used to refer to has no knowledge that y no longer refers to it (or that it did in the first place); and even if it did, y.previous_value() would call a method on the int, not on the MyClass instance.

The closest you can do is to play with __setitem__. This is the hook that Python calls when you do something like this:

x = [1, 2, 3]
x[2] = 5

the second line translates to x.__setitem__(2, 5). Using this, you can play fun games like this:

class MyClass:
    def __init__(self):
        self.values = []

    def __setitem__(self, item, value):
        self.value.append(value)

    def previousvalue(self):
        return self.values[-2]

    def __str__(self):
        return str(self.values[-1])

x = MyClass()
x[:] = 5
x[:] = 6
print(x.previousvalue())

Note that you need the [] to trigger __setitem__, and it needs to have a value - this can be any object, since it is ignored, so I use an empty slice. The fact that you need to jump through syntactic hoops like this should be a big indicator that you should rethink why you want to do this - there is almost certainly a better way to achieve your goal.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top