ZetCode

Python __abs__ 方法

最后修改于 2025 年 4 月 8 日

这份综合指南探讨了 Python 的 __abs__ 方法,该特殊方法实现了内置的 abs() 函数。我们将涵盖基本用法、数学运算、自定义数字类型和实际示例。

基本定义

__abs__ 方法是 Python 中的一个特殊方法,它定义了对对象调用 abs() 函数时的行为。它返回一个数的绝对值。

主要特征:它不接受任何参数(除了 self),必须返回一个值,并且由内置函数 abs() 自动调用。它是 Python 数字类型的运算符重载协议的一部分。

基本 __abs__ 实现

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

basic_abs.py
class MyNumber:
    def __init__(self, value):
        self.value = value
    
    def __abs__(self):
        return abs(self.value)

num = MyNumber(-5)
print(abs(num))  # Output: 5

此示例显示了一个最小的 __abs__ 实现。该方法仅使用 Python 内置的 abs() 返回实例 value 属性的绝对值。

当调用 abs(num) 时,Python 会自动调用 num.__abs__()。这允许自定义对象与 Python 的内置函数一起使用。

为复数实现绝对值

__abs__ 方法可以实现更复杂的数学运算,例如计算复数或向量的大小。

complex_abs.py
class ComplexNumber:
    def __init__(self, real, imaginary):
        self.real = real
        self.imaginary = imaginary
    
    def __abs__(self):
        return (self.real**2 + self.imaginary**2) ** 0.5
    
    def __repr__(self):
        return f"{self.real} + {self.imaginary}i"

c = ComplexNumber(3, 4)
print(abs(c))  # Output: 5.0 (sqrt(3² + 4²))

此实现使用勾股定理计算复数的大小(绝对值)。结果是复平面中到原点的距离。

这里的 __abs__ 方法演示了如何计算派生值,而不是简单地返回一个属性。这种模式在数学类中很常见。

自定义向量类的绝对值

__abs__ 方法可以表示不同的概念,例如物理或数学应用中的向量大小。

vector_abs.py
class Vector:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z
    
    def __abs__(self):
        return (self.x**2 + self.y**2 + self.z**2) ** 0.5
    
    def __repr__(self):
        return f"Vector({self.x}, {self.y}, {self.z})"

v = Vector(1, 2, 2)
print(abs(v))  # Output: 3.0 (sqrt(1 + 4 + 4))

此 Vector 类实现了 __abs__ 以返回向量的欧几里得范数(大小)。该计算将勾股定理扩展到三个维度。

此示例展示了 __abs__ 如何表示超出简单数字绝对值的特定领域的“绝对值”或“大小”概念。

带单位转换的绝对值

在计算绝对值时,__abs__ 可以结合单位转换或其他变换,这在科学计算中很有用。

temperature_abs.py
class Temperature:
    def __init__(self, kelvin):
        self.kelvin = kelvin
    
    def __abs__(self):
        return Temperature(abs(self.kelvin))
    
    def to_celsius(self):
        return self.kelvin - 273.15
    
    def __repr__(self):
        return f"{self.kelvin}K ({self.to_celsius():.1f}°C)"

temp = Temperature(-50)
abs_temp = abs(temp)
print(abs_temp)  # Output: 50K (-223.1°C)

此 Temperature 类实现了 __abs__ 以返回一个以开尔文为单位的绝对值的新 Temperature 实例。该方法在计算绝对值的同时保留了单位。

该示例演示了 __abs__ 如何返回一个新对象,而不是原始值,从而通过该操作保持类类型。

带缓存的绝对值

对于昂贵的绝对值计算,__abs__ 可以实现缓存以优化重复调用时的性能。

cached_abs.py
class BigMatrix:
    def __init__(self, data):
        self.data = data
        self._abs_cache = None
    
    def __abs__(self):
        if self._abs_cache is None:
            print("Calculating absolute value...")
            # Simulate expensive calculation
            self._abs_cache = sum(sum(abs(x) for x in row) for row in self.data)
        return self._abs_cache

matrix = BigMatrix([[1, -2], [-3, 4]])
print(abs(matrix))  # Calculates and caches
print(abs(matrix))  # Uses cached value

此示例显示了一个带有缓存的 __abs__ 实现。第一次调用执行计算并存储结果,而后续调用返回缓存的值。

当绝对值计算的计算量很大且对象是不可变的(或者相关属性没有更改)时,此模式很有用。

最佳实践

资料来源

作者

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

列出所有 Python 教程