python - 在进行二进制操作时,如何让我的 Python `set` 和 `frozenset` 子类保留它们的类型?
问题描述
我分别有一些set
和frozenset
子OCDSet
类OCDFrozenSet
。当我在二进制操作中将它们与它们的祖先类的实例一起使用时,祖先类支配了结果的类型——我的意思是,当我执行OCDFrozenSet
从 a中减去 an 之类的操作时frozenset
,我得到 a frozenset
...但是如果我反转操作中的类型(即frozenset
从OCDFrozenSet
.
像这样:
……对我来说特别令人烦恼的是,使用-=
(就地减法)会改变现有实例的类型!
我关于如何处理这类事情的知识严格来自 C++,其中操作的类型是已成定论的结论,它在(可能是模板化的)运算符重载函数中明确指定;在 Python 中,类型系统通常更加隐含,但它不像就地操作让我现在相信的那样不可预测。
那么,解决这个问题的最方便的方法是什么——我假设它涉及覆盖感兴趣的子类中的一些双下划线实例方法?
解决方案
就地操作不保证它们会就地更新对象,它完全取决于对象的类型。
Tuple、frozenset 等是不可变类型,因此无法就地更新它们。
从就地运算符的库参考中:
对于字符串、数字和元组等不可变目标,会计算更新的值,但不会将其分配回输入变量。
同样,frozenset
文档也提到了关于就地操作[源]的相同内容:
下表列出了不适用于 freezeset 的不可变实例的 set 可用操作。
现在,由于您OCDFrozenSet
没有实现__isub__
,它将回退到__sub__
返回基类类型的方法frozenset
。使用基类是因为 Python 不知道您的基类期望frozenset
从__sub__
操作中新创建的参数。
更重要的是,这是Python 2 中的一个错误,其中此类操作返回了子类实例,该修复仅移植到 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))
推荐阅读
- javascript - 为什么我的 v-date-picker 不显示 2021 年及之后的日期?
- javascript - Redux 安装后 React 应用程序不会重新加载
- react-native - 我想用 React Native 中的另一个屏幕替换屏幕的某些部分
- rest - ORDS:如何在 plsql ords 中使用 refcursor 检索 json 响应
- mysql - 在 HeidiSQL 中创建引用另一个视图的视图
- python - tf.map_fn的不同分支如何使用不同的卷积层?
- fortran - 除了我们选择的元素之外,如何对向量的所有元素求和?
- ruby-on-rails - 无法为 nuxtServerInit 设置 cookie
- python - 将 InfluxDB 的价值转化为可用的数字
- r - R - 在多个数据框中替换列名中的模式