Python中不常见OOP的原因?

时间:2011-02-25 20:02:04

标签: python oop

Python使用特殊方法来处理对象的基本行为,而不是像Java和C#那样使用它们的基类Objectobject。 Python使用__str__,当对象传递给print

时使用。{1}
>>> class Demo:
>>>   def __str__(self):
>>>     return "representation"

>>> d = Demo()
>>> print(d)
representation

len相同:

>>> class Ruler:
>>>   def __len__(self):
>>>     return 42

>>> r = Ruler()
>>> len(r)
42

我期望的是这样的事情:

>>> class Ruler:
>>>   def len(self):
>>>     return 42

>>> r = Ruler()
>>> r.len()
42

间接使用特殊方法而不是直接调用常用方法的原因是什么?

4 个答案:

答案 0 :(得分:13)

这里的原因在Python文档中有很好的解释:

http://docs.python.org/faq/design.html#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list

  

主要原因是历史。功能   用于那些操作   对于一组类型而言是通用的   它们的目的是为了工作   没有方法的对象   所有(例如元组)。也是   方便有一个功能可以   容易应用于无定形   使用时的对象集合   Python的功能特性(map(),   apply()et al)。

     

实际上,实现len(),max(),   min()作为内置函数   实际上代码少于实现   它们作为每种类型的方法。一罐   关于个别案件的狡辩但是   它是Python的一部分,它也是   迟到做出这样根本性的改变   现在。功能必须保持   避免大规模的代码破坏。

(评论中对此进行了回答,但为了未来的读者,需要将其作为真正的答案。)

答案 1 :(得分:4)

这些不是钩子。

它们只是具有特殊名称的方法。

Python中特殊方法名称的约定是__name__

内置的len,iter,str,repr(和其他)函数使用普通方法,其名称遵循特殊约定,这样我们就可以确保我们已经正确地实现了特殊方法。

特殊方法具有奇怪的名称,因此我们可以自由使用我们想要的任何名称,而不必担心碰撞。


  

obj.len()实现和使用会更加直观。

或许对你而言。对其他人来说,这可能是完全莫名其妙。

对于许多常见函数,Python都有两种方法符号和函数表示法。

首选函数表示法。

它仍然是OO编程。只有符号已被更改。

答案 2 :(得分:0)

Hooks允许重新定义标准函数的行为。考虑覆盖__add__()并使用标准中缀+运算符与添加自定义add()并使用嵌套调用。

此外,如果您定义__iter__(),则可以在for ... in循环中使用您的对象。将其与控制循环和手动推进迭代进行比较。考虑重写__call__()并将实例转换为函数,与任何其他函数一样好。这提供了极大的灵活性。

如果需要,Java会对.toString()执行相同操作,当您打印对象或将其连接到字符串时,它会隐式工作。

答案 3 :(得分:0)

不是Pythonista,所以这可能会有所不同,但如果我理解你的问题,我的印象是它是一种风格和习惯而不是行为。 Java(以及较小程度上的C#)是非常冗长,规范和正交的语言。一切都是一个对象(或者对于C#,表现就像一个 - IIRC int.toString()是有效的),你应该明确表达你的程序所做的一切。

Python更简洁,重视便利,偶尔会牺牲清晰度。您也会在C ++中看到这一点,隐式转换和操作重载。只需考虑您的toString()示例的C ++模拟:

std::ostream& operator<<(std::ostream& outstream, const Widget& rhs)
{
    return outstream << rhs.name();
}

std::cout << myWidget;
相关问题