ZetCode

Python __float__ 方法

最后修改于 2025 年 4 月 8 日

这份全面的指南探讨了 Python 的 __float__ 方法,该特殊方法负责将对象转换为浮点数。

基本定义

__float__ 方法是一个特殊方法,它定义了对象应如何转换为浮点数。 当转换对象时,它由内置的 float() 函数调用。

主要特征:它必须返回一个浮点数,在浮点数转换期间自动调用,并使自定义对象支持浮点数运算。 它是 Python 数字协议的一部分。

基本的 __float__ 实现

这是一个简单的实现,展示了 __float__ 如何与自定义类一起工作。 该方法返回对象的浮点表示。

basic_float.py
class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius
    
    def __float__(self):
        return float(self.celsius)

temp = Temperature(23.5)
print(float(temp))  # 23.5

此示例显示了一个 Temperature 类,该类以摄氏度存储温度。 __float__ 方法将存储的值作为浮点数返回。

当调用 float(temp) 时,Python 会自动调用 temp.__float__() 来获取浮点表示。 这使自定义对象可以进行浮点数运算。

将自定义对象转换为浮点数

__float__ 允许自定义对象定义其自己的转换为浮点数的转换逻辑,从而实现与数字运算的集成。

custom_conversion.py
class Fraction:
    def __init__(self, numerator, denominator):
        self.numerator = numerator
        self.denominator = denominator
    
    def __float__(self):
        return self.numerator / self.denominator

half = Fraction(1, 2)
print(float(half))  # 0.5
quarter = Fraction(1, 4)
print(float(quarter) * 100)  # 25.0

这个 Fraction 类实现了 __float__ 以返回分数的小数值。 转换使浮点运算(如乘法)成为可能。

该方法在转换为浮点数时执行除法,从而为分数对象提供最自然的浮点表示。

处理非数字值

__float__ 可以包含逻辑来处理转换为浮点数并不直接或需要特殊处理的情况。

non_numeric.py
class Measurement:
    def __init__(self, value, unit):
        self.value = value
        self.unit = unit
    
    def __float__(self):
        if self.unit == 'km':
            return float(self.value * 1000)
        elif self.unit == 'cm':
            return float(self.value / 100)
        return float(self.value)

dist1 = Measurement(5, 'km')
dist2 = Measurement(150, 'cm')
print(float(dist1))  # 5000.0
print(float(dist2))  # 1.5

这个 Measurement 类在转换为浮点数时将不同的单位转换为米。 __float__ 方法处理单位转换逻辑。

该示例演示了 __float__ 如何封装转换规则,从而使对象在数字上下文中使用时更加灵活。

__float__ 中的错误处理

如果无法进行转换,__float__ 方法应通过引发适当的异常来处理这种情况,类似于内置类型。

error_handling.py
class Percentage:
    def __init__(self, value):
        self.value = value
    
    def __float__(self):
        try:
            return float(self.value.strip('%')) / 100
        except AttributeError:
            return float(self.value) / 100
        except (ValueError, TypeError):
            raise ValueError(f"Cannot convert {self.value} to percentage")

p1 = Percentage('50%')
p2 = Percentage(0.75)
print(float(p1))  # 0.5
print(float(p2))  # 0.75
# p3 = Percentage('invalid')
# float(p3)  # Raises ValueError

这个 Percentage 类处理字符串百分比(带有“%”符号)和数值。 无效值会引发 ValueError,这与 Python 的约定相匹配。

错误处理使转换更加健壮,同时在转换失败时保持清晰的错误消息,类似于内置类型。

将 __float__ 与其他数字方法结合使用

__float__ 通常与其他数字特殊方法一起使用,以提供自定义对象的完整数字行为。

numeric_methods.py
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __float__(self):
        return (self.x**2 + self.y**2)**0.5
    
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    
    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

v1 = Vector(3, 4)
v2 = Vector(6, 8)
print(float(v1))  # 5.0 (magnitude)
print(float(v1 + v2))  # 15.0

这个 Vector 类实现了 __float__ 以返回向量的大小,同时还支持通过 __add__ 进行向量加法。

该示例显示了 __float__ 如何提供有意义的数字表示,而其他方法则处理不同的运算,从而创建完整的数字类型。

最佳实践

资料来源

作者

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

列出所有 Python 教程