Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
类_init中的Python函数指针___Python_Function_Pointers_Init - Fatal编程技术网

类_init中的Python函数指针__

类_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

在下面的代码中,类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 = 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
中,将函数绑定到实例。这实际上可以被视为“函数指针”,因此所有参数都必须显式传递。在class
B
中,将函数绑定到类,从而使函数作为方法工作。您可以将类定义
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)