gpt4 book ai didi

types - Python方法包装器类型?

转载 作者:行者123 更新时间:2023-12-03 08:48:04 25 4
gpt4 key购买 nike

Python 3 中的方法包装器类型是什么?如果我这样定义一个类:

class Foo(object):
def __init__(self, val):
self.val = val
def __eq__(self, other):
return self.val == other.val

然后做:
Foo(42).__eq__

我得到:
<bound method Foo.__eq__ of <__main__.Foo object at 0x10121d0>>

但如果我这样做(在 Python 3 中):
Foo(42).__ne__

我得到:
<method-wrapper '__ne__' of Foo object at 0x1073e50>

什么是“方法包装器”类型?

编辑:抱歉更准确: class method-wrapper__ne__ 的类型,好像我这样做:
>>> type(Foo(42).__ne__)
<class 'method-wrapper'>

__eq__ 的类型是:
>>> type(Foo(42).__eq__)
<class 'method'>

此外 method-wrapper似乎是类上任何未定义的魔法方法的类型(所以 __le____repr____str__ 等如果没有明确定义也会有这种类型)。

我感兴趣的是 method-wrapper类由 Python 使用。类上方法的所有“默认实现”都只是这种类型的实例吗?

最佳答案

似乎类型 <method-wrapper ..> CPython 将其用于在 C 代码中实现的方法。基本上该类型不包装另一种方法。相反,它将 C 实现的函数包装为绑定(bind)方法。这样<method-wrapper><bound-method> 完全一样除了它是用C实现的。

在 CPython 中有两种与此相关的特殊类型。

  • <slot wrapper>其中(至少)包装了一个 C 实现的函数。表现得像 <unbound method>在 CPython 2 中(至少有时)或 <function>在 CPython 3
  • <method-wrapper>它将 C 实现的函数包装为绑定(bind)方法。这种类型的实例有 __self__调用时用作第一个参数的属性__。

  • 如果您有 <slot wrapper>你用 __get__ 将它绑定(bind)到一个对象上获取 <method-wrapper> :
    # returns a <slot_wrapper> on both CPython 2 and 3
    sw = object.__getattribute__

    # returns a <method-wrapper>
    bound_method = sw.__get__(object())

    # In this case raises AttributeError since no "some_attribute" exists.
    bound_method("some_attribute")

    您可以调用 __get__在 Python 中的任何类似函数的对象上获取 <bound method><method-wrapper> .备注 __get__这两种类型都会简单地返回 self.

    python 3

    类型 object在 CPython 3 中, __ne__ 都有 C 实现和 __eq__ ,以及任何其他比较运算符。因此 object.__ne__返回 <slot wrapper>对于这个运营商。同样 object().__ne__返回 <method-wrapper>可用于比较 this 对象。

    由于您尚未定义 __ne__在您的类中,您会得到一个绑定(bind)方法(如 <method-wrapper> ),它是对象实例(包括派生实例)的 C 实现函数。我敢打赌,这个 C 函数将检查您是否定义了任何 __eq__ ,调用这个,然后不是结果。

    Python 2(未问但已回答)

    Python 2 在这里的表现明显不同。因为我们有未绑定(bind)方法的概念。这要求您使用正确的第一个参数类型来调用它们,两者都是 <slot wrapper><method-wrapper>有一个 __objclass__这是第一个参数必须是实例的类型。

    此外:Python 2 没有任何 object 比较运算符的实现。类型。因此 object.__ne__不是比较对象的函数。更有趣的是,类型 type这是 object 的元类确实有一个 C 实现的 __ne__运算符(operator)。因此,您会从 object.__ne__ 获得绑定(bind)方法将尝试比较类型 object与任何其他类型(或对象)。

    因此 object().__ne__实际上会失败并返回 AttributeError自从 object没有定义任何这样的方法。鉴于 object() == object()实际上有效(给出 False),我猜 CPython 2 在解释器中有用于比较对象的特殊情况。
    我们再次看到 CPython 3 已经清理了 Python 2 的一些不太幸运的实现细节。

    关于types - Python方法包装器类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10401935/

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