ZetCode

Python __neg__ 方法

最后修改于 2025 年 4 月 8 日

本综合指南探讨了 Python 的 __neg__ 方法,这是一种实现一元求反运算符 (-) 的特殊方法。我们将涵盖基本用法、数学运算、自定义类和实际示例。

基本定义

__neg__ 方法是 Python 中的一种特殊方法,用于实现一元求反运算符 (-)。当您在对象上使用 - 运算符时,Python 会调用此方法来确定结果。

主要特征:它只接受 self 作为参数,返回求反后的值,并且应该返回一个新对象,而不是修改原始对象。它为自定义类启用运算符重载。

基本 __neg__ 实现

这是一个简单的实现,展示了 __neg__ 如何与自定义数字类一起工作。 它演示了基本语法和行为。

basic_neg.py
class Number:
    def __init__(self, value):
        self.value = value
    
    def __neg__(self):
        return Number(-self.value)
    
    def __repr__(self):
        return f"Number({self.value})"

num = Number(5)
neg_num = -num
print(neg_num)  # Output: Number(-5)

此示例表明,将 - 运算符应用于 Number 实例会调用 __neg__,它返回一个具有求反值的新 Number。 原始对象保持不变。

包含 __repr__ 方法是为了更好地表示字符串,但对于 __neg__ 功能不是必需的。

数学向量求反

__neg__ 方法对于数学类特别有用,因为在这些类中,求反具有特定含义,例如向量。

vector_negation.py
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __neg__(self):
        return Vector(-self.x, -self.y)
    
    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

v = Vector(3, -4)
neg_v = -v
print(neg_v)  # Output: Vector(-3, 4)

在此向量示例中,求反返回一个新向量,其中两个分量都被求反。 这遵循标准的数学向量求反规则。

该方法保留原始向量,同时创建一个具有求反值的新向量,这是不可变对象的预期行为。

带求反的温度类

这是一个使用 __neg__ 的实际示例,用于处理摄氏和华氏刻度的温度类。

temperature_negation.py
class Temperature:
    def __init__(self, value, scale='C'):
        self.value = value
        self.scale = scale
    
    def __neg__(self):
        return Temperature(-self.value, self.scale)
    
    def convert(self):
        if self.scale == 'C':
            return Temperature(self.value * 9/5 + 32, 'F')
        else:
            return Temperature((self.value - 32) * 5/9, 'C')
    
    def __repr__(self):
        return f"{self.value}°{self.scale}"

temp = Temperature(25)
print(-temp)  # Output: -25°C
print((-temp).convert())  # Output: -13.0°F

此温度类演示了 __neg__ 仅对值求反,同时保留刻度。 转换方法显示了求反如何与其他操作交互。

请注意,求反不会自动在刻度之间转换 - 它只是对当前刻度中的数值求反。

带求反的自定义货币类

此示例显示了一个 Money 类,其中求反表示债务或负余额,这是一个常见的财务概念。

money_negation.py
class Money:
    def __init__(self, amount, currency='USD'):
        self.amount = amount
        self.currency = currency
    
    def __neg__(self):
        return Money(-self.amount, self.currency)
    
    def __add__(self, other):
        if self.currency != other.currency:
            raise ValueError("Currencies must match")
        return Money(self.amount + other.amount, self.currency)
    
    def __repr__(self):
        return f"{self.amount:.2f} {self.currency}"

balance = Money(100.50)
debt = -balance
print(debt)  # Output: -100.50 USD
print(balance + debt)  # Output: 0.00 USD

在这种财务上下文中,求反表示债务或负余额。 该示例还显示了求反如何与加法交互以清零余额。

__add__ 中的货币检查表明 __neg__ 保留所有属性(如货币),同时仅对金额求反。

矩阵求反

对于更复杂的数学对象(如矩阵),__neg__ 可以实现逐元素求反,遵循线性代数规则。

matrix_negation.py
class Matrix:
    def __init__(self, data):
        self.data = data
    
    def __neg__(self):
        neg_data = [[-elem for elem in row] for row in self.data]
        return Matrix(neg_data)
    
    def __repr__(self):
        return '\n'.join(' '.join(f"{elem:3}" for elem in row) 
                        for row in self.data)

m = Matrix([[1, 2], [3, 4]])
print("Original:")
print(m)
print("\nNegated:")
print(-m)

此矩阵实现显示了 __neg__ 如何通过将求反运算应用于每个元素来处理嵌套数据结构。

列表推导创建一个新矩阵,其中所有元素都被求反,遵循数学矩阵求反规则,同时保留结构。

最佳实践

资料来源

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。 我从 2007 年开始撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程