18

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.

5
  • 3
    I think this would violate Python's object model or variable/naming scheme. A name does not represent one object only, but just points to an object under the hood. Using the assignment operator just changes the object a name points to. Commented Aug 22, 2014 at 22:32
  • Because then, once assigning to a variable it would be impossible to do anything with that label again? Commented Aug 22, 2014 at 22:32
  • 12
    Nothing could be further from how Python works. Assignment doesn't even touch the object, it only manipulates names. You should describe what problem you're trying to solve so we can focus on how to achieve that. Commented Aug 22, 2014 at 22:33
  • @delnan Ya, that's what I feared. What I'm trying to do is implement a generalized tree object to be able to easily use with the rest of my code and PyQt5's model-view architecture. I'll put the details in the question, just a sec. Commented Aug 22, 2014 at 22:36
  • 1
    Property assignments/set'ing (for a given object) can be intercepted .. not sure if such is any use, or a path worth exploring in context, however. Ref. intermediate-and-advanced-software-carpentry.readthedocs.org/en/… Commented Aug 22, 2014 at 23:59

1 Answer 1

36

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.

Sign up to request clarification or add additional context in comments.

1 Comment

So sad.. but understandable. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.