Python 中的方法对象实现 |文档中的模棱两可的陈述
Method object implementation in Python | Ambiguous statements from the documentation
我对Python中的方法实现有些困惑。在这方面的任何帮助将不胜感激。
我找到了这个 ,它很有用,但没有回答我的问题。
我的问题:
Section 9.3.4 from Python documentation 最后一段的以下陈述对我来说不是很清楚。
When a non-data attribute of an instance is referenced, the instance’s
class is searched. If the name denotes a valid class attribute that is
a function object, a method object is created by packing (pointers to)
the instance object and the function object just found together in an
abstract object: this is the method object. When the method object is
called with an argument list, a new argument list is constructed from
the instance object and the argument list, and the function object is
called with this new argument list.
我对文档的初步理解与 @vaughn-mcgill-adami 非常相似:
当 class 实例对象调用它的方法对象时,
将在 class 对象上搜索相应的函数对象。如果找到,则调用 class 对象拥有的函数,并将 class 实例对象作为第一个参数。
但是,经过一些编码,我觉得我的理解可能不正确。原因是可以删除 class 对象。然而,调用方法对象仍然可以毫无问题地完成,而将 class 实例对象从 class 对象传递给函数对象会导致错误,因为不会有 class 对象在删除后不再存在。
以下代码片段旨在更好地解释我的问题:
class myclass:
x=0
def inc(self):
self.x +=1
print(self.x)
myobj = myclass()
type(myobj.inc) #output: method
type(myclass.inc) #output: function
# 1. calling method object multiple times
# 2. calling function object and passing the instance object multiple times
print(myobj.x)
for i in range(3):
myobj.inc()
for i in range(3):
myclass.inc(myobj)
#-------------
# output:
#-------------
# 0
# 1
# 2
# 3
# 4
# 5
# 6
#-------------
# deleting the class object
del myclass
# calling method object multiple times
for i in range(3):
myobj.inc()
#-------------
# output:
#-------------
# 7
# 8
# 9
#-------------
# calling function object and passing the instance object
for i in range(3):
myclass.inc(myobj)
#-------------
# output:
#-------------
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-177-86f094e96103> in <module>
1 for i in range(3):
----> 2 myclass.inc(myobj)
NameError: name 'myclass' is not defined
我从附带的代码片段中了解到,在实例化一个 class 对象之后,
方法对象附加到 class 实例对象。方法对象和 class 实例对象将独立于 class 对象。
以下是我从文档中得到的一些含糊之处:
“...实例的 class 被搜索”是什么意思?我相信它应该是“实例 class 对象”,但它似乎不是错字,因为在下面的句子中它说“如果名称表示一个有效的 class 属性,它是一个函数对象……”。同样,这里我认为“方法对象”应该取代“函数对象”。
“...创建了一个方法对象...”。方法对象是一调用就创建,还是class实例对象同时创建?
“通过打包(指向)刚刚找到的实例对象和函数对象”。同样,“函数对象”对我来说似乎不正确。
基本上,如果 class 对象被删除,就像我的代码片段中那样,那么首先就没有要搜索的 class 对象。也不会指向函数对象。
很有可能我在这里遗漏了什么。如果有人可以提供建议,我将不胜感激。谢谢
Basically, if the class object is deleted, as in my code snippet, then
there is no class object to be searched on in the first place. There
will be no function object to be pointed to either.
这是你根本性的误解。
del
不删除对象.
的确,Python该语言无法手动删除对象(或手动管理内存,即它是一种内存管理语言)。
del
从命名空间中删除 个名称。
当您 del myclass
时,您只是从该模块的命名空间中删除了该名称。但是 class 对象仍然存在,一方面,它被 class、my_object.__class__
的所有实例引用,并且像任何其他对象一样,只要引用到它存在。
因此,请考虑以下带有 del
的示例:
>>> x = [1,2,3]
>>> y = x
>>> print(x is y)
True
>>> print(id(x), id(y))
140664200270464 140664200270464
>>> x.append(1337)
>>> x
[1, 2, 3, 1337]
>>> y
[1, 2, 3, 1337]
>>> del x
>>> print(y)
[1, 2, 3, 1337]
所以 del
x 没有 删除对象 ,它只是从该命名空间中删除了名称 x
。所以如果我这样做:
>>> print(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
del
只能间接导致对象的删除,如果你从命名空间中删除的名称是对该对象的最后引用,则该对象对于垃圾收集是免费的(在 CPython 中,它使用引用计数作为其主要垃圾收集策略,它将立即被回收,但在其他实现中可能并非如此,例如 JYthon,它使用 Java 运行时的垃圾收集器)。
一些相关文档for the del
statement is here:
Deletion of a name removes the binding of that name from the local or
global namespace, depending on whether the name occurs in a global
statement in the same code block. If the name is unbound, a NameError
exception will be raised.
注意,另一部分,
Deletion of attribute references, subscriptions and slicings is passed
to the primary object involved; deletion of a slicing is in general
equivalent to assignment of an empty slice of the right type (but even
this is determined by the sliced object).
基本上就是说像
这样的语句
del obj[item]
委托给
type(obj).__delitem__
也就是说,它只是调用方法的糖。
我对Python中的方法实现有些困惑。在这方面的任何帮助将不胜感激。
我找到了这个
我的问题: Section 9.3.4 from Python documentation 最后一段的以下陈述对我来说不是很清楚。
When a non-data attribute of an instance is referenced, the instance’s class is searched. If the name denotes a valid class attribute that is a function object, a method object is created by packing (pointers to) the instance object and the function object just found together in an abstract object: this is the method object. When the method object is called with an argument list, a new argument list is constructed from the instance object and the argument list, and the function object is called with this new argument list.
我对文档的初步理解与 @vaughn-mcgill-adami
但是,经过一些编码,我觉得我的理解可能不正确。原因是可以删除 class 对象。然而,调用方法对象仍然可以毫无问题地完成,而将 class 实例对象从 class 对象传递给函数对象会导致错误,因为不会有 class 对象在删除后不再存在。
以下代码片段旨在更好地解释我的问题:
class myclass:
x=0
def inc(self):
self.x +=1
print(self.x)
myobj = myclass()
type(myobj.inc) #output: method
type(myclass.inc) #output: function
# 1. calling method object multiple times
# 2. calling function object and passing the instance object multiple times
print(myobj.x)
for i in range(3):
myobj.inc()
for i in range(3):
myclass.inc(myobj)
#-------------
# output:
#-------------
# 0
# 1
# 2
# 3
# 4
# 5
# 6
#-------------
# deleting the class object
del myclass
# calling method object multiple times
for i in range(3):
myobj.inc()
#-------------
# output:
#-------------
# 7
# 8
# 9
#-------------
# calling function object and passing the instance object
for i in range(3):
myclass.inc(myobj)
#-------------
# output:
#-------------
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-177-86f094e96103> in <module>
1 for i in range(3):
----> 2 myclass.inc(myobj)
NameError: name 'myclass' is not defined
我从附带的代码片段中了解到,在实例化一个 class 对象之后, 方法对象附加到 class 实例对象。方法对象和 class 实例对象将独立于 class 对象。
以下是我从文档中得到的一些含糊之处:
“...实例的 class 被搜索”是什么意思?我相信它应该是“实例 class 对象”,但它似乎不是错字,因为在下面的句子中它说“如果名称表示一个有效的 class 属性,它是一个函数对象……”。同样,这里我认为“方法对象”应该取代“函数对象”。
“...创建了一个方法对象...”。方法对象是一调用就创建,还是class实例对象同时创建?
“通过打包(指向)刚刚找到的实例对象和函数对象”。同样,“函数对象”对我来说似乎不正确。
基本上,如果 class 对象被删除,就像我的代码片段中那样,那么首先就没有要搜索的 class 对象。也不会指向函数对象。
很有可能我在这里遗漏了什么。如果有人可以提供建议,我将不胜感激。谢谢
Basically, if the class object is deleted, as in my code snippet, then there is no class object to be searched on in the first place. There will be no function object to be pointed to either.
这是你根本性的误解。
del
不删除对象.
的确,Python该语言无法手动删除对象(或手动管理内存,即它是一种内存管理语言)。
del
从命名空间中删除 个名称。
当您 del myclass
时,您只是从该模块的命名空间中删除了该名称。但是 class 对象仍然存在,一方面,它被 class、my_object.__class__
的所有实例引用,并且像任何其他对象一样,只要引用到它存在。
因此,请考虑以下带有 del
的示例:
>>> x = [1,2,3]
>>> y = x
>>> print(x is y)
True
>>> print(id(x), id(y))
140664200270464 140664200270464
>>> x.append(1337)
>>> x
[1, 2, 3, 1337]
>>> y
[1, 2, 3, 1337]
>>> del x
>>> print(y)
[1, 2, 3, 1337]
所以 del
x 没有 删除对象 ,它只是从该命名空间中删除了名称 x
。所以如果我这样做:
>>> print(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
del
只能间接导致对象的删除,如果你从命名空间中删除的名称是对该对象的最后引用,则该对象对于垃圾收集是免费的(在 CPython 中,它使用引用计数作为其主要垃圾收集策略,它将立即被回收,但在其他实现中可能并非如此,例如 JYthon,它使用 Java 运行时的垃圾收集器)。
一些相关文档for the del
statement is here:
Deletion of a name removes the binding of that name from the local or global namespace, depending on whether the name occurs in a global statement in the same code block. If the name is unbound, a NameError exception will be raised.
注意,另一部分,
Deletion of attribute references, subscriptions and slicings is passed to the primary object involved; deletion of a slicing is in general equivalent to assignment of an empty slice of the right type (but even this is determined by the sliced object).
基本上就是说像
这样的语句del obj[item]
委托给
type(obj).__delitem__
也就是说,它只是调用方法的糖。