在进行二进制操作时,如何使Python`set`和`frozenset`子类保留它们的类型?

2024-05-23 17:57:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些setfrozenset子类,分别是OCDSetOCDFrozenSet。当我在二进制运算中将它们与它们的祖先类的实例一起使用时,祖先类支配着结果的类型——我的意思是,当我从frozenset中减去一个OCDFrozenSet时,我得到一个frozenset……但是如果我在运算中反转类型(即从OCDFrozenSet中减去一个frozenset),情况也是如此。你知道吗

像这样:

enter image description here

…对我来说最让人恼火的是使用-=(就地减法)会改变现有实例的类型!你知道吗

我如何处理这种事情的知识严格地来自C++,其中操作的类型是在一个(可能模板化的)操作符重载函数中明确指定的一个放弃的结论;在Python中,类型系统通常更隐含,但这并不像我现在所相信的那样变幻莫测。你知道吗

那么,解决这个问题最方便的方法是什么呢?我假设它涉及重写感兴趣的子类中的一些双下划线实例方法?你知道吗


Tags: 实例方法函数模板类型二进制情况子类
1条回答
网友
1楼 · 发布于 2024-05-23 17:57:23

就地操作并不保证它们会就地更新对象,它完全取决于对象的类型。你知道吗

Tuple、frozenset等是不可变的类型,因此不可能就地更新它们。你知道吗

从内建运算符上的library reference

For immutable targets such as strings, numbers, and tuples, the updated value is computed, but not assigned back to the input variable.

类似地,frozenset文档也提到同样的事情about in-place operations[source]:

The following table lists operations available for set that do not apply to immutable instances of frozenset.


现在,由于OCDFrozenSet没有实现__isub__,它将回退到__sub__方法,该方法将返回基类frozenset的类型。之所以使用基类,是因为Python不知道基类在__sub__操作中新创建的frozenset上所期望的参数。你知道吗

更重要的是,这是一个bug in Python 2,其中这样的操作返回子类实例,修复方法只是ported to Python 3,尽管是为了防止破坏现有系统。你知道吗


要获得预期的输出,可以在子类中提供所需的方法:

class OCDFrozenSet(frozenset):
    def __sub__(self, other):
        return type(self)(super().__sub__(other))

    def __rsub__(self, other):
        return type(self)(super().__rsub__(other))

相关问题 更多 >