2010-09-24 16 views
53

¿Alguien puede explicarme en términos simples qué es un "método" en Python?¿Qué es un "método" en Python?

El tema está en muchos tutoriales de Python para principiantes. Esta palabra se usa de tal manera que el principiante ya sabía lo que es un método en el contexto de Python. Aunque, por supuesto, estoy familiarizado con el significado general de esta palabra, no tengo idea de qué significa este término en Python. Entonces, por favor, explíqueme de qué se trata el método "Pythonian".

Algún código de ejemplo muy simple sería muy apreciado ya que una imagen vale más que mil palabras.

+1

"many Python tutorials"? ¿De qué tutoriales específicos estás hablando? No podemos recomendar uno diferente si no sabemos lo que estás leyendo actualmente. –

+4

El método es un término general, no tiene un significado diferente en Python, probablemente por eso se usa de manera despreocupada. Ver http://en.wikipedia.org/wiki/Method_(computer_science) –

+0

@ S.Lott: Lo siento, tal vez, fui demasiado absolutista al aprobar mi opinión sobre los tutoriales de Python. – brilliant

Respuesta

66

Es una función que es un miembro de una clase:

class C: 
    def my_method(self): 
     print "I am a C" 

c = C() 
c.my_method() # Prints "I am a C" 

simple como eso!

(También hay algunos tipos de métodos alternativos, que le permiten controlar la relación entre la clase y la función. Por su pregunta, supongo que usted no está preguntando sobre eso, sino solo lo básico.)

+7

Vale la pena señalar aquí que la instancia se debe pasar manualmente al método y, por convención, se pasa como 'self'. – Skilldrick

+7

@Silldrick: Usted probablemente quiere decir lo correcto, pero su comentario tal como está implica algo incorrecto. La instancia no necesita pasarse explícita/manualmente cuando se llama a un método. Pero el método tiene que recibirlo explícitamente, es decir, debe agregar manualmente un parámetro para la instancia (que, sí, se llama 'self' por convención). – delnan

+4

@delnan - Sí, gracias por la aclaración: cuando digo que pasó manualmente en lo que realmente quiero decir es que debe recibirse explícitamente como parámetro, pero se transmite implícitamente. – Skilldrick

34

Un método es una función que toma una instancia de clase como su primer parámetro. Los métodos son miembros de clases.

class C: 
    def method(self, possibly, other, arguments): 
     pass # do something here 

Como quería saber qué significa específicamente en Python, se puede distinguir entre métodos enlazados y no vinculados. En Python, todas las funciones (y como tales también los métodos) son objetos que se pueden pasar y "jugar con". Así que la diferencia entre los métodos no unidos y ligados es:

1) métodos Bound

# Create an instance of C and call method() 
instance = C() 

print instance.method # prints '<bound method C.method of <__main__.C instance at 0x00FC50F8>>' 
instance.method(1, 2, 3) # normal method call 

f = instance.method 
f(1, 2, 3) # method call without using the variable 'instance' explicitly 

métodos Bound son métodos que pertenecen a instancias de una clase. En este ejemplo, instance.method está vinculado a la instancia llamada instance. Cada vez que se invoca ese método enlazado, la instancia pasa como primer parámetro automágicamente, que se llama self por convención.

2) métodos no unidos

print C.method # prints '<unbound method C.method>' 
instance = C() 
C.method(instance, 1, 2, 3) # this call is the same as... 
f = C.method 
f(instance, 1, 2, 3) # ..this one... 

instance.method(1, 2, 3) # and the same as calling the bound method as you would usually do 

Cuando acceda C.method (el método dentro de una clase en lugar de en el interior de una instancia), se obtiene un método no unido. Si desea llamarlo, debe pasar la instancia como primer parámetro porque el método es no vinculado a cualquier instancia.

Al conocer esa diferencia, puede hacer uso de funciones/métodos como objetos, como pasar los métodos a su alrededor. Como ejemplo de caso de uso, imagine una API que le permita definir una función de devolución de llamada, pero desea proporcionar un método como función de devolución de llamada. No hay problema, simplemente pase self.myCallbackMethod como devolución de llamada y se llamará automáticamente con la instancia como primer argumento. Esto no sería posible en lenguajes estáticos como C++ (o solo con trucos).

Espero que entiendas el punto;) Creo que eso es todo lo que debes saber sobre los conceptos básicos del método. También puede leer más sobre los decoradores classmethod y staticmethod, pero ese es otro tema.

+0

Gracias, AndiDog, por esta respuesta expandida y por el tiempo que le dedicaste. Lo estoy estudiando en este momento. – brilliant

+3

+1 para la gran explicación de enlazado vs. desatado. – snapshoe

+0

Súper interesante, gracias por la explicación. Parece una convención inusualmente agresiva para python (para cambiar todos los argumentos posteriores cuando se invoca con notación de puntos en una instancia de clase), pero definitivamente tiene sentido. –

1

Lo sentimos, pero, en mi opinión, RichieHindle tiene toda la razón al decir ese método ...

Es una función que es miembro de una clase.

Aquí está el ejemplo de una función que se convierte en el miembro de la clase. Desde entonces se comporta como un método de la clase. Vamos a empezar con la clase vacía y la función normal con un argumento:

>>> class C: 
...  pass 
... 
>>> def func(self): 
...  print 'func called' 
... 
>>> func('whatever') 
func called 

Ahora añadimos un miembro de la clase C, que es la referencia a la función. Después de que podemos crear la instancia de la clase y llamar a su método como si se define dentro de la clase:

>>> C.func = func 
>>> o = C() 
>>> o.func() 
func called 

podemos utilizar también la forma alternativa de llamar al método:

>>> C.func(o) 
func called 

El o.func siquiera manifiesta la misma manera que el método de la clase:

>>> o.func 
<bound method C.func of <__main__.C instance at 0x000000000229ACC8>> 

y podemos probar el enfoque invertido. Vamos a definir una clase y robar su método como una función:

>>> class A: 
...  def func(self): 
...   print 'aaa' 
... 
>>> a = A() 
>>> a.func 
<bound method A.func of <__main__.A instance at 0x000000000229AD08>> 
>>> a.func() 
aaa 

Hasta el momento, se ve igual. Ahora la función de robo:

>>> afunc = A.func 
>>> afunc(a) 
aaa  

La verdad es que el método no acepta 'lo que sea' argumento:

>>> afunc('whatever') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unbound method func() must be called with A instance as first 
    argument (got str instance instead) 

en mi humilde opinión, este no es el argumento en contra de método es una función que es miembro de una clase.

Más tarde se encontró el Alex Martelli's answer que básicamente dice lo mismo. Lo siento si se tiene en cuenta que la duplicación :)

+0

En delnan: escribió "No es necesario pasar la instancia explícita/manualmente cuando se llama a un método". En realidad, debes pasarlo explícitamente. La única diferencia sintáctica es que no la escribe como el primer argumento entre paréntesis. Colocarlo frente al nombre del método (separado por punto) y omitir el identificador de clase es en realidad un azúcar sináctico. – pepr

0

http://docs.python.org/2/tutorial/classes.html#method-objects

Por lo general, un método se llama justo después de que está obligado:

x.f() 

En el ejemplo MiClase, esto devolverá la cadena 'hola mundo'. Sin embargo, no es necesario llamar a un método de inmediato: x.f es un objeto de método y puede almacenarse y llamarse posteriormente. Por ejemplo :

xf = x.f 
while True: 
    print xf() 

seguirá imprimiendo hola mundo hasta el fin del tiempo.

¿Qué sucede exactamente cuando se llama a un método? Puede haber notado que se llamó a x.f() sin un argumento anterior, aunque la definición de función para f() especificó un argumento. ¿Qué pasó con el argumento?Sin duda, Python lanza una excepción cuando una función que requiere un argumento se llama sin ningún tipo - incluso si el argumento no se utiliza realmente ...

En realidad, es posible que haya adivinado la respuesta: Lo especial de métodos es que el objeto se pasa como el primer argumento de la función . En nuestro ejemplo, la llamada x.f() es exactamente equivalente a MyClass.f (x). En general, llamar a un método con una lista de n argumentos equivale a llamar a la función correspondiente con una lista de argumentos que se crea insertando el objeto del método antes del primer argumento .

Si aún no entiende cómo funcionan los métodos, un vistazo a la implementación de quizás pueda aclarar las cosas. Cuando se hace referencia a un atributo de instancia que no es un atributo de datos, se busca su clase. Si el nombre denota un atributo de clase válido que es un objeto de función, se crea un objeto de método empaquetando (punteros) el objeto de instancia y el objeto de función encontrado en un objeto abstracto: este es el objeto de método. Cuando se llama al objeto de método con una lista de argumentos , se construye una nueva lista de argumentos desde el objeto instancia y la lista de argumentos, y se llama al objeto de función con esta nueva lista de argumentos.

15

En Python, un métodoes una función que está disponible para un objeto dado debido del objeto de tipo.

Por ejemplo, si crea my_list = [1, 2, 3], el método append se puede aplicar a my_list porque es una lista de Python: my_list.append(4). Todas las listas tienen un método append simplemente porque son listas.

Como otro ejemplo, si crea my_string = 'some lowercase text', el método upper se puede aplicar a my_string, simplemente porque es una cadena de Python: my_string.upper().

Las listas no tienen un método upper, y las cadenas no tienen un método append. ¿Por qué? Porque los métodos solo existen para un objeto particular si han sido explícitamente definidos para ese tipo de objeto, y los desarrolladores de Python (hasta ahora) han decidido que esos métodos particulares no son necesarios para esos objetos particulares.

Para llamar a un método, el formato es object_name.method_name(), y los argumentos para el método se enumeran entre paréntesis. El método actúa implícitamente sobre el objeto que se está nombrando y, por lo tanto, algunos métodos no tienen ningún argumento establecido, ya que el es el único objeto necesario. Por ejemplo, my_string.upper() no tiene ningún argumento enumerado porque el único argumento requerido es el objeto en sí, my_string.

Un punto común de confusión respecto a los siguientes:

import math 
math.sqrt(81) 

Es sqrt un método del objeto math? No. Así es como llama a la función sqrt desde el módulo math. El formato que se utiliza es module_name.function_name(), en lugar de object_name.method_name(). En general, la única forma de distinguir entre los dos formatos (visualmente) es buscar en el resto del código y ver si la parte antes del período (math, my_list, my_string) se define como un objeto o un módulo.

+2

Explicado tan bien para un principiante :) –