tutorial def argument __init__ python class oop self

python - def - ¿Cuál es el propósito de uno mismo?



self python 3 (19)

¿Cuál es el propósito de la palabra self en Python? Entiendo que se refiere al objeto específico creado a partir de esa clase, pero no puedo ver por qué se debe agregar explícitamente a cada función como parámetro. Para ilustrar, en Ruby puedo hacer esto:

class myClass def myFunc(name) @name = name end end

Que entiendo, con bastante facilidad. Sin embargo, en Python necesito incluir self :

class myClass: def myFunc(self, name): self.name = name

¿Alguien puede hablarme a través de esto? No es algo que haya encontrado en mi experiencia (ciertamente limitada).


Además de todas las otras razones ya mencionadas, permite un acceso más fácil a los métodos anulados; puede llamar a Class.some_method(inst) .

Un ejemplo de donde es útil:

class C1(object): def __init__(self): print "C1 init" class C2(C1): def __init__(self): #overrides C1.__init__ print "C2 init" C1.__init__(self) #but we still want C1 to init the class too

>>> C2() "C2 init" "C1 init"


Cuando se crea una instancia de los objetos, el objeto en sí se pasa al parámetro auto.

Debido a esto, los datos del objeto están vinculados al objeto. A continuación se muestra un ejemplo de cómo le gustaría visualizar qué aspecto podrían tener los datos de cada objeto. Observe cómo se reemplaza ''self'' con el nombre de los objetos. No estoy diciendo que este diagrama de ejemplo a continuación sea completamente exacto, pero espero que sirva para un propósito en la visualización del uso del yo.

El objeto se pasa al parámetro propio para que el objeto pueda mantener sus propios datos.

Si bien esto puede no ser del todo exacto, piense en el proceso de creación de instancias de un objeto como este: cuando se crea un objeto, utiliza la clase como plantilla para sus propios datos y métodos. Sin pasar su propio nombre en el parámetro auto, los atributos y métodos de la clase permanecerían como una plantilla general y no serían referenciados (pertenecerían a) al objeto. Por lo tanto, al pasar el nombre del objeto al parámetro auto, esto significa que si se crea una instancia de 100 objetos de una clase, todos pueden realizar un seguimiento de sus propios datos y métodos.

Vea la siguiente ilustración:


Digamos que tiene una clase ClassA que contiene un método methodA definido como:

def methodA(self, arg1, arg2): # do something

y ObjectA es una instancia de esta clase.

Ahora, cuando se ObjectA.methodA(arg1, arg2) , python lo convierte internamente como:

ClassA.methodA(ObjectA, arg1, arg2)

La self variable se refiere al objeto en sí.


Eche un vistazo al siguiente ejemplo, que explica claramente el propósito de self

class Restaurant(object): bankrupt = False def open_branch(self): if not self.bankrupt: print("branch opened") #create instance1 >>> x = Restaurant() >>> x.bankrupt False #create instance2 >>> y = Restaurant() >>> y.bankrupt = True >>> y.bankrupt True >>> x.bankrupt False

Se usa / necesita el self para distinguir entre instancias.


El uso del argumento, convencionalmente llamado self no es tan difícil de entender, ¿por qué es necesario? ¿O por qué lo mencionan explícitamente? Supongo que esa es una pregunta más importante para la mayoría de los usuarios que buscan esta pregunta o, de lo contrario, tendrán la misma pregunta a medida que avanzan en el aprendizaje de python. Los recomiendo leer estos dos blogs:

pythontips.com/2013/08/07/the-self-variable-in-python-explained

Tenga en cuenta que no es una palabra clave.

El primer argumento de cada método de clase, incluido init, es siempre una referencia a la instancia actual de la clase. Por convención, este argumento siempre se llama yo. En el método init, self se refiere al objeto recién creado; en otros métodos de clase, se refiere a la instancia cuyo método fue llamado. Por ejemplo, el código siguiente es el mismo que el código anterior.

neopythonic.blogspot.com/2008/10/…

Otra cosa que me gustaría agregar es que un argumento self me permite declarar métodos estáticos dentro de una clase, al no escribir self .

Ejemplos de código:

class MyClass(): def staticMethod(): print "This is a static method" def objectMethod(self): print "This is an object method which needs an instance of a class, and that is what self refers to"

PD : esto funciona solo en Python 3.x.

En versiones anteriores, tiene que agregar explícitamente el decorador @staticmethod , de lo contrario, self argumento self es obligatorio.


En el método __init__ , self se refiere al objeto recién creado; en otros métodos de clase, se refiere a la instancia cuyo método fue llamado.

yo, como nombre, es solo una convención , llámalo como quieras! pero cuando lo usa, por ejemplo para eliminar el objeto, tiene que usar el mismo nombre: __del__(var) , donde se usó var en __init__(var,[...])

Debes echar un vistazo a cls también, para tener una imagen más grande . Esta post podría ser útil.


En primer lugar, el yo es un nombre convencional, podría poner cualquier otra cosa (ser coherente) en su lugar.

Se refiere al objeto en sí, de modo que cuando lo está utilizando, está declarando que .name y .age son propiedades de los objetos de Student (nota, no de la clase de Student) que va a crear.

class Student: #called each time you create a new Student instance def __init__(self,name,age): #special method to initialize self.name=name self.age=age def __str__(self): #special method called for example when you use print return "Student %s is %s years old" %(self.name,self.age) def call(self, msg): #silly example for custom method return ("Hey, %s! "+msg) %self.name #initializing two instances of the student class bob=Student("Bob",20) alice=Student("Alice",19) #using them print bob.name print bob.age print alice #this one only works if you define the __str__ method print alice.call("Come here!") #notice you don''t put a value for self #you can modify attributes, like when alice ages alice.age=20 print alice

El código está aquí


Es porque, por la forma en que Python está diseñado, las alternativas difícilmente funcionarán. Python está diseñado para permitir que los métodos o funciones se definan en un contexto donde tanto this implícito (a-la Java / C ++) como explícito @ (a-la ruby) no funcionarán. Vamos a tener un ejemplo con el enfoque explícito con las convenciones de python:

def fubar(x): self.x = x class C: frob = fubar

Ahora la función fubar no funcionaría, ya que supondría que self es una variable global (y también en frob ). La alternativa sería ejecutar métodos con un alcance global reemplazado (donde self es el objeto).

El enfoque implícito sería

def fubar(x) myX = x class C: frob = fubar

Esto significaría que myX se interpretaría como una variable local en fubar (y también en frob ). La alternativa aquí sería ejecutar métodos con un alcance local reemplazado que se mantenga entre las llamadas, pero eso eliminaría la posibilidad de las variables locales del método.

Sin embargo, la situación actual funciona bien:

def fubar(self, x) self.x = x class C: frob = fubar

aquí, cuando se llama como método, frob recibirá el objeto en el que se llama a través del parámetro self , y fubar todavía puede llamarse con un objeto como parámetro y funciona de la misma manera ( es lo mismo que C.frob , creo).


Es una referencia explícita al objeto de instancia de clase.


Está ahí para seguir el zen de Python "explícito es mejor que implícito". De hecho, es una referencia a su objeto de clase. En Java y PHP, por ejemplo, se llama this .

Si user_type_name es un campo en su modelo, puede acceder por self.user_type_name .


La razón por la que necesitas usar el self. es porque Python no usa la sintaxis de @ para referirse a los atributos de instancia. Python decidió hacer métodos de una manera que haga que la instancia a la que pertenece el método se pase automáticamente, pero no se reciba automáticamente: el primer parámetro de los métodos es la instancia a la que se llama el método. Eso hace que los métodos sean completamente iguales a las funciones, y deja que el nombre real se use para ti (aunque self es la convención, y la gente generalmente te frunce el ceño cuando usas otra cosa). self no es especial para el código, es simplemente otro objeto

Python podría haber hecho algo más para distinguir los nombres normales de los atributos (sintaxis especial como Ruby), o requerir declaraciones como C ++ y Java, o quizás algo más diferente, pero no fue así. Python es todo para hacer las cosas explícitas, lo que hace obvio qué es qué, y aunque no lo hace del todo en todas partes, lo hace por ejemplo, los atributos. Es por eso que asignar un atributo de instancia necesita saber a qué instancia asignar y por eso se necesita a self. .


Los siguientes extractos son de la documentación de Python sobre sí mismo :

Como en Modula-3, no hay abreviaturas [en Python] para hacer referencia a los miembros del objeto desde sus métodos: la función del método se declara con un primer argumento explícito que representa el objeto, que la llamada proporciona de manera implícita.

A menudo, el primer argumento de un método se llama self. Esto no es más que una convención: el nombre self no tiene ningún significado especial para Python. Sin embargo, tenga en cuenta que al no seguir la convención, su código puede ser menos legible para otros programadores de Python, y también es concebible que se pueda escribir un programa de explorador de clase que se base en dicha convención.

Para obtener más información, consulte el tutorial de documentación de Python sobre las clases .


Me gusta este ejemplo:

class A: foo = [] a, b = A(), A() a.foo.append(5) b.foo ans: [5] class A: def __init__(self): self.foo = [] a, b = A(), A() a.foo.append(5) b.foo ans: []


Me sorprende que nadie haya criado a Lua. Lua también usa la variable ''self'', sin embargo, se puede omitir pero aún se puede usar. C ++ hace lo mismo con ''esto''. No veo ninguna razón para tener que declarar "yo" en cada función, pero aún así debería poder usarlo como lo hace con lua y C ++. Para un lenguaje que se enorgullece de ser breve, es extraño que requiera que declare la variable propia.


Python no es un lenguaje creado para Programación Orientada a Objetos a diferencia de Java o C ++.

Al llamar a un método estático en Python, uno simplemente escribe un método con argumentos regulares dentro de él.

class Animal(): def staticMethod(): print "This is a static method"

Sin embargo, un método de objeto, que requiere que hagas una variable, que es un Animal, en este caso, necesita el argumento propio.

class Animal(): def objectMethod(self): print "This is an object method which needs an instance of a class"

El método propio también se usa para referirse a un campo variable dentro de la clase.

class Animal(): #animalName made in constructor def Animal(self): self.animalName = ""; def getAnimalName(self): return self.animalName

En este caso, self se refiere a la variable animalName de toda la clase. RECUERDE: si tiene una variable dentro de un método, no funcionará. Esa variable simplemente existe solo mientras se ejecuta ese método. Para definir campos (las variables de toda la clase), debe definirlos FUERA de los métodos de clase.

Si no entiende una sola palabra de lo que estoy diciendo, entonces "Programación Orientada a Objetos" de Google. Una vez que entiendas esto, ni siquiera necesitarás hacer esa pregunta :).


Su uso es similar al uso de this palabra clave en Java, es decir, para dar una referencia al objeto actual.


Tomemos una clase simple de vectores:

class Vector: def __init__(self, x, y): self.x = x self.y = y

Queremos tener un método que calcule la longitud. ¿Cómo sería si quisiéramos definirlo dentro de la clase?

def length(self): return math.sqrt(self.x ** 2 + self.y ** 2)

¿Qué aspecto debería tener cuando lo definiéramos como un método / función global?

def length_global(vector): return math.sqrt(vector.x ** 2 + vector.y ** 2)

Así que toda la estructura se mantiene igual. ¿Cómo puedo hacer uso de esto? Si asumimos por un momento que no habíamos escrito un método de length para nuestra clase Vector , podríamos hacer esto:

Vector.length_new = length_global v = Vector(3, 4) print(v.length_new()) # 5.0

Esto funciona porque el primer parámetro de length_global puede reutilizarse como el parámetro self en length_new . Esto no sería posible sin un self explícito.

Otra forma de entender la necesidad de un self explícito es ver dónde Python agrega algo de azúcar sintáctico. Cuando se tiene en cuenta, básicamente, una llamada como

v_instance.length()

se transforma internamente a

Vector.length(v_instance)

es fácil ver dónde encaja el self . En realidad, no se escriben métodos de instancia en Python; lo que escribes son métodos de clase que deben tomar una instancia como primer parámetro. Y por lo tanto, tendrás que colocar el parámetro de instancia en algún lugar explícitamente.


Voy a demostrar con código que no usa clases :

def state_init(state): state[''field''] = ''init'' def state_add(state, x): state[''field''] += x def state_mult(state, x): state[''field''] *= x def state_getField(state): return state[''field''] myself = {} state_init(myself) state_add(myself, ''added'') state_mult(myself, 2) print( state_getField(myself) ) #--> ''initaddedinitadded''

Las clases son solo una forma de evitar pasar esta cosa de "estado" todo el tiempo (y otras cosas agradables como la inicialización, la composición de la clase, las metaclases que rara vez se necesitan y los métodos personalizados compatibles para anular a los operadores).

Ahora vamos a demostrar el código anterior usando la maquinaria incorporada de la clase Python, para mostrar cómo es básicamente lo mismo.

class State(object): def __init__(self): self.field = ''init'' def add(self, x): self.field += x def mult(self, x): self.field *= x s = State() s.add(''added'') # self is implicitly passed in s.mult(2) # self is implicitly passed in print( s.field )

[migré mi respuesta de la pregunta cerrada duplicada]


self es una referencia de objeto al objeto en sí, por lo tanto, son iguales. Los métodos de Python no se llaman en el contexto del objeto en sí. self en Python puede usarse para tratar con modelos de objetos personalizados o algo así.