2011-10-11 20 views
17

¿Se supone que debes usar self al hacer referencia a una función miembro en Python (dentro del mismo módulo)?¿Cuándo usas 'self' en Python?

De manera más general, me preguntaba cuando es necesario para utilizar self, no sólo para los métodos, pero para las variables también.

Respuesta

20

Adición de una respuesta porque Oskarbi es no es explícita.

Se utilizan self cuando:

  1. Definición de un método de instancia. Se pasa automáticamente como el primer parámetro cuando se llama a un método en una instancia, y es la instancia en la que se llamó al método.
  2. Hace referencia a un atributo de clase o instancia desde dentro de un método de instancia. Úselo para llamar a un método o acceder a un nombre (variable) en la instancia en que se invocó el método, desde ese método.

Usted No uso self cuando

  1. se llama a un método de instancia normalmente. Usando el ejemplo de Oskarbi, si lo hace instance = MyClass(), llame al MyClass.my_method como instance.my_method(some_var) no como instance.my_method(self, some_var).
  2. Hace referencia a un atributo de clase de fuera de un método de instancia pero dentro de la definición de clase.
  3. Estás dentro de staticmethod.

Estos no son solo ejemplos de cuándo no utilizar uno mismo. Los dos son cuando debe usar.

1

Por ejemplo variable y para los métodos es obligatorio usar self en cualquier momento.

+0

Así que en caso de duda, siempre van con él? –

+0

¡Sí! Es obligatorio – lc2817

+0

@DarkTemplar Siempre usa self al _definir_ un método de instancia, o llamar a uno o hacer referencia a una variable de instancia desde un método de instancia, de lo contrario. No sé a qué se refería con "en cualquier momento", pero no es cierto, ya que se toma literalmente. – agf

11

Utilice self para hacer referencia a variables de instancia y métodos de otros métodos de instancia. También ponga self como el primer parámetro en la definición de métodos de instancia.

Un ejemplo:

class MyClass(object): 

    my_var = None 

    def my_method(self, my_var): 
     self.my_var = my_var 
     self.my_other_method() 

    def my_other_method(self): 
     # do something... 
+0

Entonces, ¿"clase MyClass (objeto)" es un constructor? Veo que 'objeto' es un parámetro pero no estoy seguro de lo que eso significa ... –

+0

@DarkTemplar Los parámetros en una definición de clase son clases base (también hay un parámetro de palabra clave, 'metaclass' para establecer el tipo de la clase en Python 3) – agf

+0

Eso no es un constructor, sino la definición de clase. Como @agf dice, 'object' es solo la clase base. Cuando crea una instancia de la clase, no tiene que pasar ningún parámetro (excepto si ha especificado un método '__init __ (self)' con más parámetros). – Oskarbi

3
  1. hay nada 'especial' sobre el nombre self. Es el nombre preferido por Pythonistas por convención, para indicar lo que se espera que contenga ese parámetro.

  2. El tiempo de ejecución de Python pasará un valor "propio" al llamar a un método de instancia en una instancia, tanto si lo proporciona deliberadamente como si no. Esto generalmente dará como resultado un error fácilmente diagnosticado/entendido (ya que la función se llamará con una cantidad incorrecta de parámetros), pero el uso de *args puede provocar errores de tipo bastante más extraños.

  3. El parámetro se pasa implícitamente al llamar a un método de instancia en una instancia. Contiene la instancia sobre la que llama al método.Por lo tanto, no mencione self en la llamada a función porque (a) como se indicó anteriormente, eso no tendría ningún sentido (no hay un self en alcance, en general, y self no es una palabra clave o nombre especial ni nada); (b) ya ha indicado la instancia para usar (escribiendo my_instance.).

  4. Puede, por supuesto, llamar explícitamente a un método de instancia accediendo a él desde la clase. En este caso, deberá pasar la instancia explícitamente como el primer parámetro. En general, no quieres hacer esto. Y usted especialmente no desea escribir código que considere la posibilidad de que el primer parámetro sea algo más que haya sido explícitamente pasado de esta manera. Esto es similar a comprobar if (this == null) en C++: no lo hace, porque si podría significar algo, entonces el código de llamada es incorrecto, moralmente si no legalmente. (Al menos en Python no tendrá problemas con un comportamiento indefinido, pero sigue siendo moralmente incorrecto).

  5. Dentro del método de instancia, dado que self es un parámetro al que se le ha asignado la instancia como valor, puede escribir self.whatever para acceder a los atributos de la instancia. A diferencia de otros lenguajes de estilo "implícitos this", los nombres de los atributos son y no implícitamente "en el alcance".

  6. No hay otros casos de uso para self, ya que nuevamente no es un nombre especial, y ese es el único propósito específico que aborda la convención de nomenclatura. Si necesita acceder a una 'variable' (realmente un atributo) de otro módulo, debe usar el nombre del módulo. Si desea acceder a uno desde el módulo actual, no se necesita ningún prefijo, o realmente es posible para ese asunto. (Bueno, usted podría buscar explícitamente en el dict devuelto por globals(), pero por favor no hacer eso.)