在 Python 中创建实例方法对象的不同方式

Xu *_*eng 4 python methods attributes instance python-3.x

Python 3.x 语言参考描述了两种创建方法对象的方法:

如果该属性是用户定义的函数对象或类方法对象,则可以在获取类的属性时(可能通过该类的实例)创建用户定义的方法对象。

当通过从类中的一个实例检索用户定义的函数对象来创建实例方法对象时,它的 self 属性是实例,并且方法对象被称为已绑定。新方法的 func 属性是原始函数对象。

当通过从类或实例中检索另一个方法对象来创建用户定义的方法对象时,其行为与函数对象相同,只是新实例的 func 属性不是原始方法对象而是其 func 属性.

当一个实例方法对象被调用时,底层函数(func)被调用,在参数列表前面插入类实例(self)。例如,当 C 是一个包含函数 f() 定义的类,而 x 是 C 的一个实例时,调用 xf(1) 等效于调用 Cf(x, 1)。

当实例方法对象派生自类方法对象时,self 中存储的“类实例”实际上就是类本身,因此调用 xf(1) 或 Cf(1) 等效于调用 f(C,1 ) 其中 f 是基础函数。

在不同的方法,它们都具有不同的__func____self__值,但我不是很清楚这两种不同的方式,可能有人解释给我吗?

Python 语言参考 | 标准类型层次结构:https : //docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy

mgi*_*son 6

我不是 100% 确定我完全理解你的问题,但也许看一个例子会有所帮助。首先,让我们创建一个在定义中具有函数的类:

>>> class Foo(object):
...   def method(self):
...     pass
... 
>>> f = Foo()
Run Code Online (Sandbox Code Playgroud)

如果该属性是用户定义的函数对象或类方法对象,则可以在获取类的属性时(可能通过该类的实例)创建用户定义的方法对象。

好的,所以我们可以通过访问实例上的属性来创建一个方法对象(如果该属性是一个函数)。在我们的设置中,f是类的一个实例Foo

>>> type(f.method)
<class 'method'>
Run Code Online (Sandbox Code Playgroud)

将其与访问上的方法属性进行比较:

>>> type(Foo.method)
<class 'function'>
Run Code Online (Sandbox Code Playgroud)

当通过其实例之一从类中检索用户定义的函数对象来创建实例方法对象时,其 __self__ 属性是实例,并且方法对象被称为绑定。新方法的 __func__ 属性是原始函数对象。

这只是告诉我们实例方法上存在哪些属性。让我们来看看:

>>> instance_method = f.method
>>> instance_method.__func__ is Foo.method
True
>>> instance_method.__self__ is f
True
Run Code Online (Sandbox Code Playgroud)

所以我们看到方法对象有一个__func__属性,它只是对实际Foo.method函数的引用。它还有一个__self__属性是对实例的引用。

当一个实例方法对象被调用时,底层函数(func)被调用,在参数列表前面插入类实例(self)。例如,当 C 是一个包含函数 f() 定义的类,而 x 是 C 的一个实例时,调用 xf(1) 等效于调用 Cf(x, 1)。

基本上,参考我们上面的例子,这只是说如果:

instance_method = f.method
Run Code Online (Sandbox Code Playgroud)

然后:

instance_method(arg1, arg2)
Run Code Online (Sandbox Code Playgroud)

执行以下操作:

instance_method.__func__(instance_method.__self__, arg1, arg2)
Run Code Online (Sandbox Code Playgroud)