对象模型在动态语言中的实现差异

在过去几周内,我对 Ruby 对象模型进行了深入的研究。以前我只是使用 Ruby 和 Python 对象模型的成果,而现在我很好奇这些东西在其他语言中的实现会有何不同。多年前,我接触过 Smalltalk 的 Squeak 版本。Smalltalk 通常被认为是一种参考性的面向对象语言,这也是我对它感兴趣的原因。Ruby 对象模型不区分对象和类,存在单例对象使每个对象成为了一个原型,必要时可进行扩展。据我所知,所有这些都是作为元对象协议定义的。这些特性让编程比 C++ 或 Java 等其他不太动态或非动态语言更加轻松。
在这里插入图片描述

请给出一个概念,说明动态语言,特别是 Smalltalk、Python 和 Ruby 在实现元对象协议方面的差异是什么?

  1. 解决方案

Python 和 Smalltalk 之间的主要区别在于属性隐私处理方式。在 Smalltalk 中,我定义了属性,并必须立即生成所有访问器(幸运的是,Dolphin Smalltalk 做到了这一点)并使用它们。另一方面,在 Python 中,一切都可访问,即使是那些被认为是私有的属性(以 __ 开头,被破坏为 ___)。有些人可能会说这是潜在危险的——例如,在未来的某个时刻,你需要在更改某些属性时执行某些操作。但 Python 通过属性很好地解决了这个问题。

我喜欢我可以访问我想要的一切的想法。如果我只知道自己在做什么,我就可以做到 😃

在 Python 中,每个对象都有一个命名空间——对象的“属性”,可在此命名空间中访问,可以是方法、对其他对象(可调用或不可调用)的简单引用,或者由描述符动态生成(普通属性可能存在于实例或类中,但描述符——包括用作描述符的函数,用于合成方法——仅在存在于类中时才使用,而不是实例中;因此,尤其是“特殊方法”仅当在类中定义时才特殊,而不是在实例中)。属性处理内置函数和特殊方法(getattr、setattr、getattrsetattr 等)对于对象的单个命名空间以相同的方式工作,无论引用的是“普通属性”还是不是。

关键在于,对于任何对象 a,在 Python 中,a.b 可以是方法(或其他可调用对象)或不是:Python 编译器不知道(也不关心),你可以获取引用 a.b 并(例如)将其作为参数传递,将其作为结果返回,将其附加到列表中,等等,这些操作都不意味着调用 a.b。如果你想(尝试)调用 a.b,你可以通过后缀括号显式地这样做:a.b(),如果你想在没有参数的情况下调用它。

在 Ruby 中,对象的函数和属性存在于不同的命名空间中(因此你可以拥有一个具有函数和属性(同名)的对象,在 Python 中你无法拥有),并且“仅仅提到”一个无参数函数会隐式地调用它(因此 c=a.b 可能只是获取属性引用,或者可能调用 a.b();如果 b 在 a 中同时命名了一个函数和一个属性,我不记得使用了什么启发式规则来消除歧义)。因此,如果你只想获取函数引用(例如,存储在某个容器中或用作参数或返回值),稍后执行调用,你应该使用不同的语法。

Smalltalk 也有单独的命名空间,就像 Ruby 一样,但你无法引用给定对象的“非函数”属性(每个对象只能“看到”自己的属性),因此不会出现这种歧义(但你仍然必须使用特定的消息来提取并稍后调用“函数引用”)。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值