如何动态合并两个对象,使对新对象的操作同步作用于原对象?
如何在运行时动态创建同步操作两个原对象的新对象?
我们需要实现一个通用方案,在运行时动态生成一个新对象,对这个新对象执行的任意操作都会同步作用于两个原对象。
举个具体的例子:我们有两个流对象,一个是字符串流,一个是文件流,希望向新流写入内容时,内容会同时写入这两个原流。以下是针对这个场景的简单实现:
import io class MergedStream: def __init__(self, strm1, strm2): self._strm1 = strm1 self._strm2 = strm2 def write(self, msg: str): self._strm1.write(msg) self._strm2.write(msg) return None str_strm = io.StringIO() fl_strm = open("test_file.txt", "w") ms = MergedStream(str_strm, fl_strm)
但这个方案只针对write方法,不具备通用性——我们需要不管原对象是什么类型、拥有哪些方法/属性,新对象都能将所有操作同步到两个原对象上。
下面是一个初步的通用实现思路,但代码并不完整(已修正原代码中的基础语法错误):
class MergedObject: @classmethod def merge(cls, left, right): if left == right: return left else: return cls(left, right) def __call__(self, *args, **kwargs): try: r1 = self._lefty(*args, **kwargs) r2 = self._righty(*args, **kwargs) return type(self).merge(r1, r2) except AttributeError: raise AttributeError() def __init__(self, lefty, righty): self._lefty = lefty self._righty = righty reserved = dir(self) # 保留的属性名称 attribute_names = set(dir(lefty) + dir(righty)).difference(reserved) for attribute_name in attribute_names: latter = getattr(lefty, attribute_name) # 获取左侧对象的对应属性 ratter = getattr(righty, attribute_name) # 获取右侧对象的对应属性 setattr(self, attribute_name, type(self).merge(latter, ratter))
现在需要解决两个核心问题:
- 能够正确判断两个未重载
__eq__运算符的对象是否相等,避免重复计算。比如合并两个值为10的对象时,执行x +5不会对两个对象分别计算,而是只计算一次。 - 正确处理Python魔术方法(如
__len__、__mul__)的重载,避免原对象都具备某魔术方法时,合并后的对象却无法调用该方法。
内容的提问来源于stack exchange,提问作者Toothpick Anemone
相关产品推荐
相关产品推荐

