为什么 Python 使用“魔术方法”?

新手上路,请多包涵

我最近一直在玩 Python,我发现有点奇怪的是广泛使用“魔术方法”,例如,为了使其长度可用,一个对象实现了一个方法, def __len__(self) ,然后在您编写 len(obj) 时调用它。

我只是想知道为什么对象不简单地定义一个 len(self) 方法并将其作为对象的成员直接调用,例如 obj.len() ?我确信 Python 这样做一定有充分的理由,但作为新手,我还没有弄清楚它们是什么。

原文由 Greg Beech 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 561
2 个回答

AFAIK, len 在这方面很特别并且有历史根源。

是常见问题解答中 的引述:

为什么 Python 对某些功能(例如 list.index())使用方法,而对其他功能(例如 len(list))使用函数?

主要原因是历史。函数用于那些对一组类型通用的操作,并且旨在甚至对根本没有方法的对象(例如元组)也起作用。当您使用 Python 的功能特性(map()、apply() 等)时,拥有一个可以轻松应用于无定形对象集合的函数也很方便。

事实上,将 len()、max()、min() 作为内置函数实现实际上比将它们作为每种类型的方法实现代码更少。可以对个别情况提出异议,但它是 Python 的一部分,现在进行此类根本性更改为时已晚。必须保留这些功能以避免大量代码损坏。

其他“神奇方法”(实际上在 Python 民间传说中称为 _特殊方法_)很有意义,其他语言中也存在类似的功能。它们主要用于在使用特殊语法时隐式调用的代码。

例如:

  • 重载运算符(存在于 C++ 和其他语言中)
  • 构造函数/析构函数
  • 访问属性的钩子
  • 元编程工具

等等…

原文由 Eli Bendersky 发布,翻译遵循 CC BY-SA 2.5 许可协议

来自 Python 之禅:

面对模棱两可的情况,拒绝猜测的诱惑。

应该有一种——最好只有一种——显而易见的方法来做到这一点。

这是原因之一 - 使用自定义方法,开发人员可以自由选择不同的方法名称,例如 getLength()length()getlength() 。 Python 强制执行严格的命名,以便可以使用通用函数 len()

许多类型对象的所有通用操作都放入魔术方法中,例如 __nonzero____len____repr__ 不过,它们大多是可选的。

运算符重载也是通过魔术方法完成的(例如 __le__ ),因此将它们用于其他常见操作也很有意义。

原文由 AndiDog 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题