类_init中的Python函数指针__
在下面的代码中,类A有一个成员函数,该函数被设置为指向类外部定义的函数。 在类B中,将相同的函数设置为类定义中的外部指针。 为类型为A的对象调用函数将失败,因为没有将self传递给函数。但对于B来说,自我会被忽略。 为什么自我被认为是B,而不是A类_init中的Python函数指针__,python,function,pointers,init,Python,Function,Pointers,Init,在下面的代码中,类A有一个成员函数,该函数被设置为指向类外部定义的函数。 在类B中,将相同的函数设置为类定义中的外部指针。 为类型为A的对象调用函数将失败,因为没有将self传递给函数。但对于B来说,自我会被忽略。 为什么自我被认为是B,而不是A def f1(s,a): print s print a class A(object): def __init__(self): self.fp1 = f1 class B(object): fp1
def f1(s,a):
print s
print a
class A(object):
def __init__(self):
self.fp1 = f1
class B(object):
fp1 = f1
a=A()
b=B()
try:a.fp1("blaa")
except Exception, e: print `e`
try:b.fp1("bluu")
except Exception, e: print `e`
输出:
TypeError('f1() takes exactly 2 arguments (1 given)',)
<__main__.B object at 0x2ab0dacabed0>
bluu
TypeError('f1()正好接受2个参数(给定1个),)
布鲁
在第一种情况下,您在类中创建了一个字段,其中存储了一个方法对象。因此“a.fp1”不是方法调用,因此“a”不是第一个参数。它是一个方法对象的检索,然后调用它
对于第二种情况,您可以参考:
作为类属性的任何函数对象都定义了
该类的实例
因此,对于b,“fp1”成为类b实例的方法
您可以在这里找到更详细的解释:当您执行
self.fp1=f1
时,您刚刚为类a
的实例变量分配了一个函数。所以当你调用它时,你必须传递两个参数
当你这么做的时候:
class B(object):
fp1 = f1
在类B
的创建过程中,python在类作用域中找到了一个函数fp1
,并从中创建了一个instancemethod
(将名为fp1
的变量替换为从它之前持有的函数创建的instancemethod
)。在对象上调用instancemethod
时,self
会自动作为第一个参数传递
您可以通过键入以下内容进行检查:
>>> a = A()
>>> b = B()
>>> type(a.fp1)
function
>>> type(b.fp1)
instancemethod
使
instance.method(…)
等价于Class.method(instance,…)
的魔力取决于作为类属性的函数对象。细节各不相同(同时,创建这样一个方法的难看的解决方法也不相同)。在Python3中,所有函数都是。在Python2中,有一些特殊的未绑定方法对象,隐式创建这些对象是为了包装存储为类属性的函数,并大致完成Python3中所有函数自己所做的工作
在任何一种情况下,通过实例访问它都会创建一个绑定方法,该方法在调用时将实例作为第一个参数传递。在任何一种情况下,通过实例属性访问的函数都不是特别的,它只是可以传递和使用的另一个对象
您可以通过使用partial
(有点漏洞百出的抽象)来实现类似的行为:
或者通过创建一个方法来委托:
def __init__(self):
self._fp1 = f1
def fp1(*args, **kwds):
return self._fp1(self, *args, **kwds)
在类
A
中,将函数绑定到实例。这实际上可以被视为“函数指针”,因此所有参数都必须显式传递。在classB
中,将函数绑定到类,从而使函数作为方法工作。您可以将类定义A
修改为
class A(object):
def __init__(self):
A.fp1 = f1
将给出相同行为的类有B
,即所有实例的fp1
指向f1
,或者您可以换行f1
class A(object):
def __init__(self):
self.fp1 = lambda a: f1(self, a)
这将允许对每个实例分别更改fp1
。后一种变体可能就是您所寻找的
class A(object):
def __init__(self):
self.fp1 = lambda a: f1(self, a)