过去可以在运行时设置内部函数,如__len__()
。举个例子:
#! /usr/bin/python3
import sys
class FakeSequence:
def __init__(self):
self.real_sequence = list()
self.append = self.real_sequence.append
self.__len__ = self.real_sequence.__len__
def workaround__len__(self):
return len(self.real_sequence)
if __name__ == '__main__':
fake_sequence = FakeSequence()
fake_sequence.append(1)
fake_sequence.append(2)
fake_sequence.append(3)
length = len(fake_sequence)
sys.stdout.write("len(fake_sequence) is %d\n" % (length))
以下是您尝试运行它时的结果:
$ python2 len_test
len(fake_sequence) is 3
$ python3 len_test
Traceback (most recent call last):
File "len_test", line 18, in <module>
length = len(fake_sequence)
TypeError: object of type 'FakeSequence' has no len()
如果我将__len__()
方法定义为类的一部分(删除上面的“变通方法”),它将按照您的预期工作。如果我定义__len__()
并如上所述重新分配FakeSequence.__len__()
,它就不会访问新分配的__len__()
,它总是调用FakeSequence类方法。你知道吗
你能给我指出一些文档来帮助解释为什么为成员函数分配实例方法不再有效吗?请注意,指定非双下划线方法仍然可以正常工作。我可以很容易地解决这个问题,我更担心的是,在从python2到python3的转换过程中,我遗漏了一些基本的东西。上面的行为与我可以轻松访问的python3解释器(3.4、3.6、3.7)是一致的。你知道吗
魔术方法只在类上查找,而不是在实例上,如documented here。Py2中的新样式类(cfhttps://docs.python.org/2.7/reference/datamodel.html#special-method-lookup-for-new-style-classes)也是如此。你知道吗
我认为主要的动机是为了减少寻找更好的表现,但可能还有其他原因,我不知道。你知道吗
编辑:实际上,the motivations are clearly explained in the 2.7 doc:
然后:
最后:
因此,这实际上主要是一种性能优化—当您了解Python's attribute lookup mechanism和how Python's "methods" are implemented时,这并不奇怪。你知道吗
在Python 3中测试:
您可以创建自己的函数,比如
mylen
,并将其传递给类的构造函数。下面的示例使用始终返回5的函数mylen
:文档here中描述了这种行为。这与Python2和Python3中的新样式和旧样式类有关。换句话说,如果您继承了
object
,那么在python2中就不应该这样做。您发布的代码使用python2中的旧样式类和python3中的新样式类。你知道吗docs声明,为了通过绕过查找来提高优化速度,“必须在类对象本身上设置特殊方法,以便解释器一致地调用它。”
相关问题 更多 >
编程相关推荐