gpt4 book ai didi

python - 在自定义 Python 类中动态重新分配 __len__

转载 作者:行者123 更新时间:2023-12-04 23:11:48 24 4
gpt4 key购买 nike

以前可以设置内部函数,如 __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 类方法。

您能否指出有助于解释为什么为成员函数分配实例方法不再有效的文档?请注意,分配非双下划线方法仍然可以正常工作。我可以很容易地解决这个问题,但我更担心我错过了从 Python 2 到 Python 3 过渡的一些基本内容。 上述行为与我可以轻松访问的 Python 3 解释器一致 (3.4, 3.6, 3.7) .

最佳答案

魔术方法只在类上查找,而不在实例上查找,如 documented here .在 Py2 中,新式类也是这种情况(参见 https://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 :

The rationale behind this behaviour lies with a number of special methods such as hash() and repr() that are implemented by all objects, including type objects. If the implicit lookup of these methods used the conventional lookup process, they would fail when invoked on the type object itself:


然后:

Incorrectly attempting to invoke an unbound method of a class in this way is sometimes referred to as ‘metaclass confusion’, and is avoided by bypassing the instance when looking up special methods:


最后:

In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the getattribute() method even of the object’s metaclass

Bypassing the getattribute() machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods


所以这确实主要是性能优化 - 当您了解 Python's attribute lookup mechanism 时,这并不奇怪和 how Python's "methods" are implemented .

关于python - 在自定义 Python 类中动态重新分配 __len__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59381104/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com