Python方法包装器类型? [英] Python method-wrapper type?

查看:56
本文介绍了Python方法包装器类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

class Foo(object):def __init__(self, val):self.val = valdef __eq__(自我,其他):返回 self.val == other.val

然后做:

Foo(42).__eq__

我明白了:

>

但如果我这样做(在 Python 3 中):

Foo(42).__ne__

我明白了:

<0x1073e50 处 Foo 对象的方法包装器__ne__">

什么是方法包装器"类型?

抱歉更准确:class method-wrapper__ne__ 的类型,就像我这样做:

<预><代码>>>>类型(Foo(42).__ne__)<类'方法包装器'>

__eq__ 的类型是:

<预><代码>>>>类型(Foo(42).__eq__)<类'方法'>

此外,method-wrapper 似乎是类上任何未定义魔法方法的类型(所以 __le__, __repr__, __str__ 等如果未明确定义也将具有此类型).

我感兴趣的是 Python 如何使用 method-wrapper 类.类中方法的所有默认实现"是否都只是这种类型的实例?

解决方案

这是因为 Python 3 中不存在未绑定方法".

<块引用>

在 Python 3000 中,未绑定方法的概念已被删除,表达式A.spam"返回一个普通的函数对象.结果证明,第一个参数必须是 A 的实例这一限制对诊断问题几乎没有帮助,而且常常是高级用法的障碍——有人称其为鸭子输入自我",这似乎是一个合适的名称.(来源)

在 Python 2.x 中,我们有绑定方法和未绑定方法.绑定方法绑定到一个对象,这意味着当它被调用时,它将对象实例作为第一个变量(self,通常)传递.未绑定方法是指函数是方法,但没有它所属的实例的方法 - 如果将对象实例以外的其他内容传递给方法,则会引发错误.

现在,在 3.x 中,这已经改变了.而不是绑定/未绑定方法,当你请求一个对象的方法时,它返回函数对象,但是包裹在一个传入实例变量的包装函数中. 这样就不需要区分绑定和未绑定方法- 绑定的方法被包装,未绑定的不是.

澄清区别:

2.x:

a = A()f = A.method # f 是一个未绑定的方法 - 您必须将 `A` 的一个实例作为第一个参数传递给它.f = a.method # f 是绑定方法,绑定到实例`a`.

3.x:

a = A()f = A.method # f 是一个函数f = a.method # f 是一个包装函数,它的第一个参数用 `a` 填充.

a.method 可以被认为是:

def method-wrapper():A.方法(一)

有关这方面的更多信息,请查看 Guido 的博客 - Python 的历史.

所以,这一切都适用的原因是,这里 __ne__() 没有被覆盖 - 它处于默认状态,即身份检查,在 C 中实现(第 980 行).包装器用于为方法提供上述功能.

What is the method-wrapper type in Python 3? If I define a class like so:

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

And then do:

Foo(42).__eq__

I get:

<bound method Foo.__eq__ of <__main__.Foo object at 0x10121d0>>

But if I do (in Python 3 ):

Foo(42).__ne__

I get:

<method-wrapper '__ne__' of Foo object at 0x1073e50>

What is a "method-wrapper" type?

Edit: sorry to be more accurate: class method-wrapper is the type of __ne__, as if I do:

>>> type(Foo(42).__ne__)
<class 'method-wrapper'>

Whereas the type of __eq__ is:

>>> type(Foo(42).__eq__)
<class 'method'>

Furthermore method-wrapper seems to be the type of any undefined magic method on a class (so __le__, __repr__, __str__ etc if not explicitly defined will also have this type).

What I am interested in is how the method-wrapper class is used by Python. Are all "default implementations" of methods on a class just instances of this type?

解决方案

This is because 'unbound methods' don't exist in Python 3.

In Python 3000, the concept of unbound methods has been removed, and the expression "A.spam" returns a plain function object. It turned out that the restriction that the first argument had to be an instance of A was rarely helpful in diagnosing problems, and frequently an obstacle to advanced usages --- some have called it "duck typing self" which seems an appropriate name. (Source)

In Python 2.x, we had bound methods and unbound methods. A bound method was bound to an object, meaning that when it was called, it passed the object instance as the first variable (self, normally). An unbound method was one where the function was a method, but without a instance it belonged to - it would throw an error if something other than an object instance was passed in to the method.

Now, in 3.x, this has been changed. Instead of bound/unbound methods, when you request a method of an object, it returns the function object, but wrapped in a wrapper function that passes the instance variable in. This way there is no need to make a distinction between bound and unbound methods - bound methods are wrapped, unbound are not.

To clarify the difference:

2.x:

a = A()
f = A.method # f is an unbound method - you must pass an instance of `A` in to it as the first argument.
f = a.method # f is a bound method, bound to the instance `a`.

3.x:

a = A()
f = A.method # f is a function
f = a.method # f is a wrapped function with it's first argument filled with `a`.

a.method can be thought of as:

def method-wrapper():
    A.method(a)

For more on this, check out Guido's blog - the history of Python.

Edit:

So, the reason this all applies is that, here, __ne__() has not been overridden - it's at a default state, which is an identity check, implemented in C (line 980ish). The wrapper is there to provide the method with the above functionality.

这篇关于Python方法包装器类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆