2011-08-18 74 views
7

所以我知道在Python中,一切都是'对象',这意味着它可以作为参数传递给方法。但我试图了解这项工作到底如何。所以我尝试了下面的例子:python方法作为参数

class A: 

    def __init__(self): 
     self.value = 'a' 

    def my_method(self) 
     print self.value 

class B: 

    def __init__(self): 
     self.values = 'b' 

    def my_method(self, method): 
     method() 

a = A() 
b = B() 
b.my_method(a.my_method) 

现在第一个这是为了看看事情是如何工作的。我知道我应该例如检查my_method的参数是否可以调用。现在我的问题是:

这个方法到底在哪里?我的意思是我收到的输出是'a',所以我猜测,当一个对象方法作为参数传递,那么实际的对象呢?在这种情况下,当我通过a.my_method实例a也通过?

+2

如果你使用Python 2,使用'class A(object):'而不是'class A:'来获得“新风格的类”,这通常更好,你应该使用什么。 –

回答

8

当访问a.my_method Python看到,它是类的一个属性,并且A.my_method有一个方法__get__()所以它调用A.my_method.__get__(a),该方法创建新的对象(即“结合的方法”),其含有两个至A.my_method参考并提及a本身。当您调用绑定方法时,它会将回调传递回基础方法。

每次您调用任何方法时都会发生这种情况,不管您是直接调用它,还是像在代码中一样,将实际的调用延迟到以后。您可以在http://docs.python.org/reference/datamodel.html#descriptors

+0

感谢您的输入。 Python可能会很棘手,直到你习惯它:D – Bogdan

4

该方法在这里传递的方式是什么?

这很容易回答:在Python中,一切都是对象:)也是函数/方法,它们是可作为参数传递的特定函数对象。

在这种情况下,当我通过a.my_method实例a也被传递?

是的,在这种情况下,实例a也被传递,尽管嵌入在函数对象中并且不能被检索。相反,你可以传递函数本身并提供一个实例。请看下面的例子:

b = B() 
func = A.my_method # Attention, UPPERCASE A 
func(b) 

这将调用A类方法my_methodB一个实例。

+0

严格来说,A.my_method既不是函数本身,也是* unbound *方法对象。 a.my_method是一个* bound *方法对象。如果你真的需要(检查模块),你可以从a.my_method中检索一个实例和原始函数,但我没有看到在这里做的理由。 –

+0

我试过你的建议,但只有它的工作方式是,如果A.my_method是一个具有obj参数的静态方法。否则,它期望A. – Bogdan

1

中找到描述符协议的更多描述。函数是Python中的“第一类对象”。这意味着一个函数就像一个列表或一个整数一样是一个对象。当你定义一个函数时,你实际上是将函数对象绑定到你在def中使用的名字。

函数可以绑定到其他名称或作为参数传递给函数(或存储在列表中,或...)。

源:http://mail.python.org/pipermail/tutor/2005-October/042616.html

1

a.my_method返回不完全是你在class A定义(可以通过A.my_method得到它),但函数的对象被称为“绑定的方法”,其包含原始功能(或“未结合的方法'在Python 2中,IIRC)和从中检索它的对象(self参数)。