Avoid __setitem__call when override inplace operator (original) (raw)

I want to do the following:

a[0] //= b 

which a is a custom class object, and it will perform some special operation.

So for class, a will be something like:

class a:
  def __ifloordiv__(self, i):
    #do something to the class itself
    return self

  def __getitem__(self, key):
    # special getter logic
    ...

  def __setitem__(self, v):
    # special setter logic
   ...

Is it possible for to disallow a[0] = b (by raise error in the__setitem__) but keep a[0] //= b working?

Rosuav (Chris Angelico) May 7, 2025, 11:18am 2

Is a[0] also a custom object? If your goal here is to have a[0] do some sort of mutation, and then you want a to allow that mutation but not allow reassignment, what you can do is something like:

class Stuff(list):
    def __setitem__(self, key, value):
        if self[key] is value: return
        raise TypeError("No poking me!")

class Thing:
    def __ifloordiv__(self, other):
        self.divided_by = other
        return self

a = Stuff([Thing()])
a[0] //= 2
print(a[0].divided_by)

You get to choose the rules of assignment in __setitem__, but only on the basis of what the object is, not whether it just got mutated. So it requires some cooperation from the object itself.