我最近一直在使用Python,我发现有一件事有点奇怪,那就是‘魔术方法’的广泛使用,例如,为了使它的长度可用,一个对象实现了一个方法,def __len__(self)
,然后当你编写len(obj)
时,它被调用。
我只是想知道为什么对象不简单地定义一个len(self)
方法,并将其作为对象的成员直接调用,例如obj.len()
?我相信Python这样做肯定有很好的理由,但作为一个新手,我还没有弄清楚它们是什么。
发布于 2010-04-18 03:12:07
这些函数中的一些功能超过了单个方法所能实现的功能(没有超类上的抽象方法)。例如,bool()
的行为有点像这样:
def bool(obj):
if hasattr(obj, '__nonzero__'):
return bool(obj.__nonzero__())
elif hasattr(obj, '__len__'):
if obj.__len__():
return True
else:
return False
return True
您还可以100%地确定bool()
将始终返回True或False;如果您依赖一个方法,则不能完全确定您将获得什么。
其他一些实现相对复杂(比底层魔术方法更复杂)的函数是iter()
和cmp()
,以及所有属性方法(getattr
、setattr
和delattr
)。像int
这样的东西在执行强制时也会访问魔法方法(您可以实现__int__
),但作为类型具有双重作用。len(obj)
实际上是我认为它与obj.__len__()
没有什么不同的一个例子。
发布于 2010-04-17 16:53:45
它们并不是真正的“魔法名字”。它只是一个对象为了提供给定服务而必须实现的接口。从这个意义上说,它们并不比您必须重新实现的任何预定义接口定义更神奇。
发布于 2010-04-20 06:29:53
上面两篇文章没有什么可补充的,但所有的“魔术”功能都不是真正的魔术。它们是__ builtins__模块的一部分,该模块在解释器启动时隐式/自动导入。即:
from __builtins__ import *
每次在你的程序启动前都会发生。
我一直认为,如果Python只对交互式shell执行此操作,并且需要脚本从它们所需的内置组件中导入各个部分,则会更正确。另外,在shells中使用不同的__ main__处理方式可能会比交互方式更好。无论如何,检查所有的函数,看看没有它们会是什么样子:
dir (__builtins__)
...
del __builtins__
https://stackoverflow.com/questions/2657627
复制相似问题