2011-08-18 16 views
7

Así que sé que en python todo es un 'objeto', lo que significa que se puede pasar como argumento a un método. Pero estoy tratando de entender cómo funciona esto exactamente. Así que estaba tratando el siguiente ejemplo:método de python como argumento

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) 

Ahora por primera vez este fue escrito sólo para ver cómo funcionan las cosas. Sé que debería, por ejemplo, verificar si el argumento my_method es invocable. Ahora mi pregunta es:

¿Cómo se transmite exactamente el método aquí? Me refiero a que la salida que estoy recibiendo es 'a', así que supongo que cuando se pasa un método de objeto como parámetro, ¿cuál es el objeto real? En este caso, cuando paso a.my_method, ¿también se pasa la instancia a?

+2

Si está trabajando con Python 2, use 'clase A (objeto):' en lugar de 'clase A:' para obtener "clases de estilo nuevo" que generalmente son mejores y con qué debería trabajar. –

Respuesta

8

Al acceder a.my_method Python ve que es un atributo de la clase y que A.my_method tiene un método __get__() por lo que llama A.my_method.__get__(a), ese método crea un nuevo objeto (el 'método de atado') que contiene una referencia a A.my_method y una referencia a a. Cuando llamas al método enlazado devuelve la llamada al método subyacente.

Esto ocurre cada vez que llama a un método, ya sea que lo llame directamente o, como en su código, retrase la llamada real hasta más tarde. Puede encontrar más descripciones del protocolo descriptor como se lo conoce en http://docs.python.org/reference/datamodel.html#descriptors

+0

Gracias por las entradas. Python puede ser complicado hasta que te acostumbres: D – Bogdan

4

¿Cómo se transmite exactamente el método aquí?

Esto se responde fácilmente: en Python, todo es un objeto :) También funciona/métodos, que son objetos de funciones específicas que se pueden pasar como parámetros.

En este caso, cuando paso a.my_method, también se pasa la instancia a?

Sí, en este caso también se pasa la instancia a, aunque incrustada en el objeto de función y no se puede recuperar. Por el contrario, podría pasar la función y proporcionarle una instancia. Consideremos el siguiente ejemplo:

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

Esto requeriría el método A clases my_method con una instancia de B.

+0

Estrictamente hablando, A.my_method no es la función en sí misma, sino un objeto de método * unbound *. a.my_method es un objeto de método * bound *. Podría recuperar la instancia a y la función original de a.my_method si realmente lo necesita (inspeccionar el módulo), pero no veo una razón para hacerlo aquí. –

+0

Intenté su sugerencia, pero la única forma en que funcionó fue si A.my_method era un método estático que tenía un argumento obj. De lo contrario, espera una instancia de A. – Bogdan

1

Las funciones son 'objetos de primera clase' en Python. Lo que eso significa es que una función es un objeto tanto como una lista o un número entero. Cuando define una función, en realidad está vinculando el objeto de función al nombre que usa en la definición.

Las funciones pueden vincularse a otros nombres o pasarse como parámetros a funciones (o almacenadas en listas, o ...).

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

1

a.my_method retornos no es exactamente la función que ha definido en la class A (lo puede conseguir a través de A.my_method) sino un objeto llamado 'método vinculado' que contiene tanto la función original (o 'método no unida 'en Python 2, IIRC) y el objeto del que se recuperó (el argumento self).

Cuestiones relacionadas