深度解密 Python 的浮点数是怎么实现的?

假设我们要将两个浮点数相加,相信你已经知道解释器会如何做了?通过 PyFloat_AsDouble 将两个浮点数的 ob_fval 抽出来,然后相加,最后再根据相加的结果创建一个新的 PyFloatObject 即可。

假设我们要将两个浮点数相加,相信你已经知道解释器会如何做了?通过 PyFloat_AsDouble 将两个浮点数的 ob_fval 抽出来,然后相加,最后再根据相加的结果创建一个新的 PyFloatObject 即可。

楔子

从现在开始,我们就来分析 Python 的内置对象,看看它们在底层是如何实现的。但说实话,我们在前面几篇文章中介绍对象的时候,已经说了不少了,不过从现在开始要进行更深入的分析。

除了对象本身,还要看对象支持的操作在底层是如何实现的。我们首先以浮点数为例,因为它是最简单的,没错,浮点数比整数要简单,至于为什么,等我们分析整数的时候就知道了。

浮点数的底层结构

要想搞懂浮点数的实现原理,就要知道它在底层是怎么定义的,当然在这之前我们已经见过它很多遍了。

// Include/cpython/floatobject.h
typedef struct {
    PyObject_HEAD
    double ob_fval;
} PyFloatObject;

它包含了一个公共头部 PyObject 和一个 double 类型的 ob_fval 字段,毫无疑问这个 ob_fval 字段负责存储浮点数的具体数值。

我们以 e = 2.71 为例,底层结构如下。

图片图片

还是很简单的,每个对象在底层都是由结构体表示的,这些结构体中有的字段负责维护对象的元信息,有的字段负责维护具体的值。比如这里的 2.71,总要有一个字段来存储 2.71 这个值,而这个字段就是ob_fval。所以浮点数的结构非常简单,直接使用一个 C 的 double 来维护。

假设我们要将两个浮点数相加,相信你已经知道解释器会如何做了?通过PyFloat_AsDouble将两个浮点数的ob_fval抽出来,然后相加,最后再根据相加的结果创建一个新的 PyFloatObject 即可。

浮点数是怎么创建的

下面来看看浮点数是如何创建的,在前面的文章中,我们说对象可以使用对应的特定类型 API创建,也可以通过调用类型对象创建。

调用类型对象 float创建实例对象,解释器会执行元类type的 tp_call,它指向了 type_call 函数。然后 type_call 内部会先调用类型对象(这里是 float)的tp_new为其实例对象申请一份空间,申请完毕之后对象就已经创建好了。然后再调用tp_init,并将实例对象作为参数传递进去,进行初始化,也就是设置属性

但是对于 float 来说,它内部的tp_init字段为0,也就是空。

图片图片

这就说明 float 没有__init__,因为浮点数太过简单,只需要一个 tp_new 即可。我们举个例子:

class Girl1:

    def __init__(self, name, age):
        self.name = name
        self.age = age

# __new__  负责开辟空间、生成实例对象
# __init__ 负责给实例对象绑定属性

# 但其实 __init__ 所做的工作可以直接在 __new__ 当中完成
# 换言之有 __new__ 就足够了,其实可以没有 __init__
# 我们将上面的例子改写一下
class Girl2:

    def __new__(cls, name, age):
        instance = object.__new__(cls)
        instance.name = name
        instance.age = age
        return instance

g1 = Girl1("古明地觉", 16)
g2 = Girl2("古明地觉", 16)
print(g1.__dict__ == g2.__dict__)  # True

我们看到效果是等价的,因为 __init__ 负责给 self 绑定属性,而这个 self 是__new__ 返回的。那么很明显,我们也可以在 __new__ 当中绑定属性,而不需要 __init__。

©本文为清一色官方代发,观点仅代表作者本人,与清一色无关。清一色对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。本文不作为投资理财建议,请读者仅作参考,并请自行承担全部责任。文中部分文字/图片/视频/音频等来源于网络,如侵犯到著作权人的权利,请与我们联系(微信/QQ:1074760229)。转载请注明出处:清一色财经

(0)
打赏 微信扫码打赏 微信扫码打赏 支付宝扫码打赏 支付宝扫码打赏
清一色的头像清一色管理团队
上一篇 2024年5月31日 17:04
下一篇 2024年5月31日 17:05

相关推荐

发表评论

登录后才能评论

联系我们

在线咨询:1643011589-QQbutton

手机:13798586780

QQ/微信:1074760229

QQ群:551893940

工作时间:工作日9:00-18:00,节假日休息

关注微信