为什么 object.__setattr__.__get__(self, Attribute) 在 attrs/_make.py 中用于属性的 __init__

Why is object.__setattr__.__get__(self, Attribute) used for Attribute's __init__ in attrs/_make.py

我喜欢使用 attr 并决定阅读一些源代码。以下是引起我注意的部分 (source):

# Cache this descriptor here to speed things up later.
bound_setattr = _obj_setattr.__get__(self, Attribute)

# Despite the big red warning, people *do* instantiate `Attribute`
# themselves.
bound_setattr("name", name)
bound_setattr("default", default)
bound_setattr("validator", validator)

其中 _obj_setattr 定义为 object.__setattr__

我很好奇为什么要这样做。我已经阅读了 Whosebug 回复,发现它非常有用,但它没有涵盖关于 __get__ 的部分。我已经阅读了一些关于 descriptors 的内容,但还没有完全理解它们。所以,我的问题是,为什么使用 _obj_setattr.__get__(self, A)("name", name),而不是 object.__setattr__(self, "name", name)

调用函数的 __get__ 方法 returns 绑定方法对象。通常,您通过直接在实例上执行查找来执行此操作,例如 self.__setattr__。但是这段代码预计会在 __setattr__ 方法可能在子类中被覆盖的情况下使用,因此直接查找 object.__setattr__ 并将其绑定到 self 是首选。

虽然您可以执行 object.__setattr__(self, "name", name) 等等,但每次使用它时,速度会慢一点(因为属性查找不是很快,我们需要它 object.__setattr__), 而且不是很方便,因为我们总是需要手动传递 self 。将方法绑定到 self 可以让我们的性能稍微好一点,打字也更方便,所以这是双赢的。