创建一个对我们来说很方便的包装类

2024-09-26 18:19:07 发布

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

为了跟踪循环中不断更新的某些变量的当前值和以前的值,我创建了一个包装器类,在更新时自动将旧值存储在其中:

class Updatable:
    def __init__(self, value=None, prev_value=None):
        # Initial conditions
        self._value = value
        self._prev_value = prev_value

    @property
    def value(self):
        return self._value

    @property
    def prev_value(self):
        return self._prev_value

    def update(self, new_value):
        self._prev_value = self._value
        self._value = new_value

    def has_value(self):
        return self._value is not None

    def has_prev_value(self):
        return self._prev_value is not None

但是,为了让它更像一个普通变量一样工作,我希望所有的普通操作符都能像预期的那样工作(除了赋值,赋值在Python中不能重载),所以我定义了很多类可以拥有的特殊方法:

    # Object representation
    def __str__(self):
        return str(self._value)

    def __repr__(self):
        return repr(self._value)

    # Iteration
    def __len__(self):
        return len(self._value)

    def __getitem__(self, key):
        return self._value[key]

    def __reversed__(self):
        return reversed(self._value)

    # Arithmetic operations
    def __add__(self, other):
        return self._value + other

    def __sub__(self, other):
        return self._value - other

    def __mul__(self, other):
        return self._value * other

    def __matmul__(self, other):
        return self._value @ other

    def __truediv__(self, other):
        return self._value / other

    def __floordiv__(self, other):
        return self._value // other

    def __mod__(self, other):
        return self._value % other

    def __divmod__(self, other):
        return divmod(self._value, other)

    def __pow__(self, other, *args):
        return pow(self._value, other, *args)

    def __lshift__(self, other):
        return self._value << other

    def __rshift__(self, other):
        return self._value >> other

    def __and__(self, other):
        return self._value & other

    def __xor__(self, other):
        return self._value ^ other

    def __or__(self, other):
        return self._value | other

    # Comparison operators
    def __eq__(self, other):
        return self._value == other

    def __ne__(self, other):
        return self._value != other

    def __lt__(self, other):
        return self._value < other

    def __gt__(self, other):
        return self._value > other

    def __le__(self, other):
        return self._value <= other

    def __ge__(self, other):
        return self._value >= other

虽然这看起来像是很多特殊的方法,但它离all special methods还很远,而且支持所有这些方法将意味着比我已经拥有的更多的锅炉板代码。你知道吗

此外,定义这些特殊方法不允许在二进制操作中使用实例作为第二个操作数。例如,代码

a = Updatable(2)
a + 3

工作,代码

a = Updatable(2)
3 + a

导致错误TypeError: unsupported operand type(s) for +: 'int' and 'Updatable',如果要方便使用,这是不可取的。你知道吗

有没有其他方法来创建一个包装类,它使用起来(几乎)和直接使用它包装的数据类型一样方便(忽略了这样一个事实:当使用裸数据类型时,除非显式存储它,否则您将无法访问上一个值)?你知道吗


Tags: 方法代码selfnonenewreturnisvalue
1条回答
网友
1楼 · 发布于 2024-09-26 18:19:07

将此添加到类定义中:

# Arithmetic operations
def __radd__(self, other):
    return other + self._value

def __add__(self, other):
    return self._value + other 

然后呢

a = Updatable(2)
3 + a

输出:

5

使用原始函数定义__add__

a = Updatable(2)
a + 3

输出:

5

相关问题 更多 >

    热门问题