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.
You can overload the assignment operator (=) just as you can other operators and it can be used to create an object just like the copy constructor.
We can overload all existing operators but we can't create a new operator. To perform operator overloading, Python provides some special function or magic function that is automatically invoked when it is associated with that particular operator.
Overloading the assignment operator (operator=) is fairly straightforward, with one specific caveat that we'll get to. The assignment operator must be overloaded as a member function. This will call f1. operator=(f1), and under the simplistic implementation above, all of the members will be assigned to themselves.
Like other languages (for example, method overloading in C++) do, python does not support method overloading by default.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With