为什么绑定类实例方法与绑定类方法不同?

yos*_*uri 13 python

我正在阅读python 文档并偶然发现以下几行:

同样重要的是要注意,作为类实例属性的用户定义函数不会转换为绑定方法;这只发生在函数是类的属性时。

请有人用简单的英语解释这意味着什么。

我将介绍一些速记符号:

让“用户定义函数”由f表示,

让“类实例”由ci表示,而仅由c表示。显然(?), ci = c(), 有一些符号滥用。

此外,允许成员声明以简单的集合表示法重铸,例如“作为类实例属性的用户定义函数”的简写是“ vf: f?a(ci) ”,其中v : ' for all ' 和 where ' a ' 是(一组)属性(例如类或类实例的)和 '?' 的简写 表示集合隶属函数。

此外,绑定函数的过程通过 ci.f(*args) 或 cf(*args) => f(ci, *args) 或 f(c, *args)(前者指的是实例方法调用而后者指的是方法调用)

使用新引入的速记符号,文档中的引用是否暗示

vf: f?a(c), cf(*args) => f(c, *args) 是一个真实的陈述

尽管

vf: f?a(ci), ci.f(*args) => f(ci, *args) 是假的?

Avi*_*niv 12

将用户定义的方法设置为类的属性,错误的方法

考虑以下示例类A和函数f


class A:
    pass

def f(self):
    print("I\'m in user-defined function")

a = A()

Run Code Online (Sandbox Code Playgroud)

该函数f是单独定义的,而不是在类内部。

假设您想将函数添加fa对象的实例方法。

添加它,通过设置fa属性,将不起作用:

import types

class A:
    pass

def f(self):
    print("I\'m in user-defined function")

a = A()
a.f = f

# <function f at 0x000002D81F0DED30>
print(a.f)

# TypeError: f() missing 1 required positional argument: 'self'
# a.f()
Run Code Online (Sandbox Code Playgroud)

因为函数f没有绑定到对象a

这就是为什么在调用a.f()它时会引发关于缺少参数的错误(如果f已绑定到a,则该对象a是缺少的参数self)。

这部分是文档中提到的:

同样重要的是要注意,作为类实例属性的用户定义函数不会转换为绑定方法。

当然,如果f在 class 中定义了函数,则所有这些都不会发生A,这就是文档中的以下部分所述:

...这只发生在函数是类的属性时。

将用户定义的方法设置为类的属性,正确的方法

要将函数添加f到对象,a您应该使用:

import types

class A:
    pass

def f(self):
    print("I\'m in user-defined function")

a = A()

a.f = types.MethodType( f, a )

# <bound method f of <__main__.A object at 0x000001EDE4768E20>>
print(a.f)

# Works! I'm in user-defined function
a.f()
Run Code Online (Sandbox Code Playgroud)

它将用户定义的方法绑定f到 instance a