Inversus
Inversus

Reputation: 3175

Is it possible to override the assignment ('=') operator in Python?

Is there a dunder for this? Perhaps something along the lines of: (updated)

class Tree:
    def __init__(self, item_or_tree):
        self._setto(item_or_tree)

    def __assign__(self, val):
        self._setto(item_or_tree)

    def __setitem__(self, which, to_what):
        ## I would like this to call __assign__ on the Tree object at _tree[which]
        to_what._tree[which] = to_what

    def __getitem__(self, which):
        return self._tree[which]

    def __len__(self): return len(self._tree)

    def __eq__(self, other):
        if isinstance(other, Tree):
            if other._is_tree:
                return (self._item == other._item) and (self._tree == other._tree)
            else:
                return self._item == other._item
        else: return self._item == other

    def _setto(self, item_or_tree):
        if isinstance(item_or_tree, Tree):
            self._set_from_Tree(item_or_tree)
        elif isinstance(item_or_tree, dict):
            self._set_from_dict(item_or_tree)
        else:
            self._set_from_other(item_or_type)


    def _set_from_Tree(self, other_Tree):
        self._tree = other_Tree[:]
        self._item = other_Tree
        self._is_tree = other_Tree._is_tree

    def _set_from_dict(self, the_dict):
        self._is_tree = True
        self._item = None
        self._tree = {}
        for key, val in the_dict.items():
            self._tree[key] = Tree(val)

    def _set_from_other(self, other):
        self._is_tree = False
        self._tree = None
        self._item = other

class TreeModel(Tree, QAbstractItemModel):
    ...
    ## a whole bunch of required overrides
    ## etc
    ...

What I'm trying to do is implement a generalized tree structure that acts as intuitively (to me) as possible and also seamlessly integrates with PyQt5's Model-View-Delegate architecture.

I want to be able to set the incoming item_or_tree to either the item or tree. So I'm looking to overload the function that's called when the = operator is used on the item.

PyQt has this item based architecture in which a QAbstractItemModel is overridden. This is (I guess) supposed to return / accept QModelIndex objects. These are trees of tables (2D arrays).

So I'm creating a single tree structure that can contain itself, deal with the 2 opposing indexing paradigms, and plays nice with Python and everything else.

Upvotes: 18

Views: 13380

Answers (1)

Ned Batchelder
Ned Batchelder

Reputation: 375584

It is not possible to override the implementation of x = y. See Facts and Myths about Python Names and Values for details of what assignment means.

You can override x.a = y, with __setattr__, it is (roughly) x.__setattr__('a', y).

You can override x[k] = y with __setitem__, it is (roughly) x.__setitem__(k, y).

But you can't override x = y.

Upvotes: 36

Related Questions