You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自动生成Python Vector类的重载运算符以避免重复代码?

解决Vector类运算符重载重复代码的方案

当然有办法搞定这种重复代码的问题!你完全不用一次次复制粘贴那些几乎一样的运算符重载方法,利用Python的动态特性就能自动生成它们,既减少冗余又降低出错概率。

核心思路

你的Vector类里,所有运算符重载方法(比如__add__、__radd__)的逻辑高度一致:都是调用私有类方法_op,只是传入的操作符函数(比如operator.add)和rev参数不同。我们可以把这些映射关系整理成一个字典,然后通过动态添加类方法的方式自动生成这些重载方法。

实现方式1:动态在类外生成方法

这种方式适合在现有类的基础上补充方法,代码如下:

import operator

class Vector:
    def __init__(self, value):
        self._vals = value.copy()
    
    @classmethod
    def _op(cls, this, that, oper, rev=False):
        assert isinstance(this, cls)
        if rev:
            op = lambda a, b : oper(b, a)
        else:
            op = oper
        if isinstance(that, list):
            result = [op(x, y) for (x, y) in zip(this._vals, that)]
        elif isinstance(that, cls):
            result = [op(x, y) for (x, y) in zip(this._vals, that._vals)]
        else:
            # assume other is scalar
            result = [op(x, that) for x in this._vals]
        return cls(result)
    
    def __str__(self):
        return str(self._vals)

# 定义方法名与操作参数的映射
operator_mappings = {
    '__add__': (operator.add, False),
    '__radd__': (operator.add, True),
    '__sub__': (operator.sub, False),
    '__rsub__': (operator.sub, True),
    '__mul__': (operator.mul, False),
    '__rmul__': (operator.mul, True),
    '__truediv__': (operator.truediv, False),
    '__rtruediv__': (operator.truediv, True),
}

# 动态生成并绑定运算符方法
def generate_operator_method(oper, rev):
    def method(self, other):
        return Vector._op(self, other, oper, rev)
    return method

for method_name, (oper, rev) in operator_mappings.items():
    setattr(Vector, method_name, generate_operator_method(oper, rev))

实现方式2:使用类装饰器(更整洁)

如果你想让类的定义更干净,可以用类装饰器来封装运算符方法的生成逻辑:

import operator

def add_vector_operators(cls):
    # 定义运算符映射
    operator_mappings = {
        '__add__': (operator.add, False),
        '__radd__': (operator.add, True),
        '__sub__': (operator.sub, False),
        '__rsub__': (operator.sub, True),
        '__mul__': (operator.mul, False),
        '__rmul__': (operator.mul, True),
        '__truediv__': (operator.truediv, False),
        '__rtruediv__': (operator.truediv, True),
    }
    
    # 动态生成方法并绑定到类
    def generate_method(oper, rev):
        def method(self, other):
            return cls._op(self, other, oper, rev)
        return method
    
    for method_name, params in operator_mappings.items():
        setattr(cls, method_name, generate_method(*params))
    return cls

@add_vector_operators
class Vector:
    def __init__(self, value):
        self._vals = value.copy()
    
    @classmethod
    def _op(cls, this, that, oper, rev=False):
        assert isinstance(this, cls)
        if rev:
            op = lambda a, b : oper(b, a)
        else:
            op = oper
        if isinstance(that, list):
            result = [op(x, y) for (x, y) in zip(this._vals, that)]
        elif isinstance(that, cls):
            result = [op(x, y) for (x, y) in zip(this._vals, that._vals)]
        else:
            # assume other is scalar
            result = [op(x, that) for x in this._vals]
        return cls(result)
    
    def __str__(self):
        return str(self._vals)

验证效果

你可以用以下代码测试生成的方法是否正常工作:

v1 = Vector([1, 2, 3])
v2 = Vector([4, 5, 6])

print(v1 + v2)       # 输出 [5, 7, 9]
print(v1 * 2)        # 输出 [2, 4, 6]
print(3 + v1)        # 输出 [4, 5, 6]
print(v2 - v1)       # 输出 [3, 3, 3]
print(10 / v1)       # 输出 [10.0, 5.0, 3.3333333333333335]

额外优势

  • 以后如果需要添加新的运算符(比如地板除法__floordiv__、取模__mod__),只需要在operator_mappings字典里加一行映射即可,不用重复写方法逻辑。
  • 避免了复制粘贴可能带来的拼写错误或者参数不一致问题。

内容的提问来源于stack exchange,提问作者MikeL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:58:37