He estado programando en varios lenguajes como Java, Ruby, Haskell y Python. Tengo que cambiar entre muchos idiomas por día debido a los diferentes proyectos en los que trabajo. Ahora, el problema es que a menudo me olvido de escribir, self
ya que el primer parámetro en las definiciones de funciones en Python es llamar a métodos en el mismo objeto.
Dicho esto, estoy bastante sorprendido por este enfoque de Python. Básicamente, tenemos que escribir más para hacer las cosas, en los lenguajes como Java y Ruby las cosas se simplifican al hacer referencia automática a las variables en el objeto actual.
Mi pregunta es ¿por qué es esto self
necesario? ¿Es puramente una elección de estilo, o hay una razón por la cual Python no puede permitirte omitir self
la forma en que Java y C ++ te permiten omitir this
?
@staticmethod
antes de la declaración del método, suprime el error (solo para información y tampoco recomendado)Respuestas:
1) ¿Por qué se
self
requiere como parámetro explícito en las firmas de métodos?Porque los métodos son funciones y
foo.bar(baz)
solo es azúcar sintácticabar(foo, baz)
. Las clases son solo diccionarios donde algunos de los valores son funciones. (Los constructores también son solo funciones, por lo que Python no necesitanew
). Puede decir que Python hace explícito que los objetos se crean a partir de componentes más simples. Esto está de acuerdo con la filosofía "explícito es mejor que implícito".En contraste, en Java los objetos son realmente mágicos y no pueden reducirse a componentes más simples en el lenguaje. En Java (al menos hasta Java 8), una función siempre es un método propiedad de un objeto, y esta propiedad no se puede cambiar debido a la naturaleza estática del lenguaje. Por lo tanto, no hay ambigüedad sobre lo que se
this
refiere, por lo que tiene sentido tenerlo implícitamente definido.JavaScript es un ejemplo de un lenguaje que tiene un lenguaje implícito
this
como Java, pero donde las funciones pueden existir por separado de los objetos como en Python. Esto lleva a mucha confusión sobre lo que sethis
refiere a cuando las funciones se pasan y se llaman en diferentes contextos. Muchos piensan instintivamente quethis
deben referirse a alguna propiedad intrínseca de la función, mientras que en realidad está puramente determinada por la forma en que se llama a la función. Creo que tenerthis
un parámetro explícito como en Python haría esto mucho menos confuso.Algunos otros beneficios del
self
parámetro explícito :Los decoradores son solo funciones que envuelven otras funciones. Como los métodos son solo funciones, los decoradores funcionan igual de bien en los métodos. Si hubiera algún tipo de yo implícito, los decoradores no funcionarían de manera transparente en los métodos.
Los métodos de clase y los métodos estáticos no toman un parámetro de instancia. Los métodos de clase toman una clase como primer argumento (típicamente llamado
cls
). El explícitoself
o loscls
parámetros aclaran mucho más lo que está sucediendo y a qué tiene acceso en el método.2) ¿Por qué las variables de instancias siempre deben calificarse con "
self.
?En Java, no necesita prefijar las variables miembro con "
this.
", pero en Python "self.
" siempre es necesario. La razón es que Python no tiene una sintaxis explícita para declarar variables, por lo que no habría forma de saber six = 7
se supone que debe declarar una nueva variable local o asignarla a una variable miembro. Especificarself.
resuelve esta ambigüedad.fuente
self.
, como Java) es fundamentalmente incompatible con las reglas de alcance y cuando necesita ser explícito allí, ser implícito sobre el parámetro ya no tiene tanto sentido.Hay una razón bastante simple por la que AFAIK realmente no se ha tratado en el duplicado entre sitios, ni aquí: Python comenzó como un lenguaje de procedimiento. Se basó en ABC, también un lenguaje de procedimiento.
La orientación a objetos se agregó más tarde, y cuando se agregó, Guido van Rossum quería agregar la cantidad mínima de características posibles, para mantener el diseño de Python simple. Python ya tenía
dict
s y funciones, entonces, ¿por qué agregar algo completamente nuevo al lenguaje, cuando un objeto puede ser simplemente unadict
de las ranuras y una clase puede ser simplemente unadict
de las funciones? Un método puede interpretarse como una función parcialmente aplicada que se cierra sobre un único argumento distinguido. Y así es precisamente cómo se implementan los métodos en Python: no lo son. Son solo funciones que reciben un argumento distinguido adicional.fuente
Aquí están mis conclusiones basadas en las respuestas anteriores y leyendo las divagaciones de Guido sobre este tema:
La gran idea
Las funciones son los bloques de construcción importantes en Python (o deberíamos decir el único), de hecho, estamos emulando a OOP mediante el uso de funciones.
Dado que una clase no es más que un diccionario de funciones, podemos adjuntar cualquier función a cualquier clase en tiempo de ejecución. Básicamente, debido a esta necesidad de utilizar las funciones en tiempo de ejecución, podemos hacer cosas como Monkey Patching . Aquí el
self
parámetro que soporta el polimorfismo paramétrico.fuente