在Python中可以重载赋值运算符('=')吗?

17 投票
1 回答
12306 浏览
提问于 2025-04-18 18:14

有没有什么特别的方式可以做到这一点?也许可以考虑以下的方式:(更新)

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
    ...

我想做的是实现一个通用的树形结构,尽量让它使用起来直观一些,同时也能和PyQt5的模型-视图-代理架构无缝结合。

我希望能够将传入的item_or_tree设置为项目或树。所以我想重载在使用=操作符时调用的函数。

PyQt有一种基于项目的架构,其中QAbstractItemModel被重写。这应该是用来返回或接受QModelIndex对象的。这些对象就像是表格的树形结构(二维数组)。

所以我正在创建一个可以包含自己的单一树形结构,能够处理两种相对的索引方式,并且能很好地与Python及其他一切配合。

1 个回答

32

你不能改变 x = y 这个赋值的方式。想了解赋值的具体含义,可以查看 关于Python名称和值的事实与误区

不过,你可以改变 x.a = y 这种写法的行为,使用 __setattr__ 方法,简单来说就是 x.__setattr__('a', y)

同样,你也可以通过 __setitem__ 来改变 x[k] = y 的行为,差不多就是 x.__setitem__(k, y)

但是,x = y 这个赋值方式是不能被改变的。

撰写回答