请看一个简单的例子:
class A:
def __init__(self, flag):
self.flag = flag
def func(self):
print self.flag
a = A(1)
b = A(2)
callback_a = a.func
callback_b = b.func
callback_a()
callback_b()
Run Code Online (Sandbox Code Playgroud)
结果是:
1
2
Run Code Online (Sandbox Code Playgroud)
它按预期运行.但我有一个问题.在C中,回调函数作为指针传递.在Python中,它应该有类似的方法来执行此操作,因此调用者知道函数的地址.但在我的例子中,不仅传递了函数指针,而且传递了参数(self),因为同一类的相同方法打印出不同的结果.所以我的问题是:
Python中的这种方法在内存中只有一个副本吗?我的意思是任何方法的代码只有一个副本,在我的例子中,该方法不会被克隆.我认为它应该只有一个副本,但在这里我仍然提出这个问题,以获得更多的输入.
我记得Python中的所有内容都是一个对象.所以在我的例子中,是否有两个具有不同参数但只有一个代码副本的函数实例?
Gre*_*ill 19
在Python中,回调不仅仅是对成员函数的引用.相反,它被"绑定"到它创建时引用的对象.因此a.func创建一个绑定的可调用对象a,并b.func创建一个绑定的可调用对象b.
Python只需要func()内存中的一个实现,但它可能会在运行时创建一个或多个"trampoline"函数来完成绑定(我不确定这方面的内部细节,无论如何它在Python实现之间会有所不同).
如果你打印id(callback_a),id(callback_b)你会得到不同的结果,表明它们确实是不同的可调用对象.
aar*_*ing 16
特定于CPython,只有一个函数对象的副本.在实例创建期间,类将未绑定的函数作为绑定方法包装在其名称空间中.但它们都包含相同的功能.
这是您的示例扩展,以显示正在发生的事情.
class A(object):
def __init__(self, flag):
self.flag = flag
def func(self):
print self.flag
a = A(1)
b = A(2)
callback_a = a.func
callback_b = b.func
print "typeof(callback_a) = {0}".format(type(callback_a))
print "typeof(callback_b) = {0}".format(type(callback_b))
print "typeof(callback_a.__func__) = {0}".format(type(callback_a.__func__))
print "typeof(callback_b.__func__) = {0}".format(type(callback_b.__func__))
print "'callback_a.__func__ is callback_b.__func__' is {0}".format(callback_a.__func__ is callback_b.__func__)
callback_a()
callback_b()
Run Code Online (Sandbox Code Playgroud)
此代码输出
typeof(callback_a) = <type 'instancemethod'>
typeof(callback_b) = <type 'instancemethod'>
typeof(callback_a.__func__) = <type 'function'>
typeof(callback_b.__func__) = <type 'function'>
'callback_a.__func__ is callback_b.__func__' is True
Run Code Online (Sandbox Code Playgroud)
您可以使用is运算符清楚地看到两个instancemethod类共享相同的函数对象.
| 归档时间: |
|
| 查看次数: |
16228 次 |
| 最近记录: |