Al definir un método en una clase en Python, se ve así:
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
Pero en algunos otros lenguajes, como C #, tiene una referencia al objeto al que está vinculado el método con la palabra clave "this" sin declararlo como un argumento en el prototipo del método.
¿Fue esta una decisión intencional de diseño de lenguaje en Python o hay algunos detalles de implementación que requieren la aprobación de "self" como argumento?
self
a los miembros de acceso - stackoverflow.com/questions/910020/...Respuestas:
Me gusta citar el Zen de Python de Peters. "Explícito es mejor que implícito".
En Java y C ++, '
this.
' se puede deducir, excepto cuando tiene nombres de variables que hacen que sea imposible de deducir. Entonces a veces lo necesitas y a veces no.Python elige hacer que cosas como esta sean explícitas en lugar de basarse en una regla.
Además, dado que no se implica ni se supone nada, se exponen partes de la implementación.
self.__class__
,self.__dict__
y otras estructuras "internas" están disponibles de manera obvia.fuente
Es para minimizar la diferencia entre métodos y funciones. Le permite generar fácilmente métodos en metaclases o agregar métodos en tiempo de ejecución a clases preexistentes.
p.ej
También (hasta donde yo sé) facilita la implementación del tiempo de ejecución de Python.
fuente
self
en la declaración de función (tenga en cuenta que tal vez esto es arrojar piedras desde una casa de cristal, ya que JavaScript tiene algunasthis
semánticas de encuadernación bastante difíciles )Sugiero que se lea el blog de Guido van Rossum sobre este tema: por qué el ser explícito tiene que quedarse .
fuente
Python no te obliga a usar "self". Puedes darle el nombre que quieras. Solo debe recordar que el primer argumento en un encabezado de definición de método es una referencia al objeto.
fuente
@staticmethod
él no lo es.También le permite hacer esto: (en resumen, la invocación
Outer(3).create_inner_class(4)().weird_sum_with_closure_scope(5)
devolverá 12, pero lo hará de la manera más loca.Por supuesto, esto es más difícil de imaginar en lenguajes como Java y C #. Al hacer explícita la autorreferencia, puede referirse a cualquier objeto mediante esa autorreferencia. Además, tal forma de jugar con las clases en tiempo de ejecución es más difícil de hacer en los idiomas más estáticos, no es necesariamente bueno o malo. Es solo que el ser explícito permite que exista toda esta locura.
Además, imagine esto: nos gustaría personalizar el comportamiento de los métodos (para perfilar, o alguna magia negra loca). Esto puede llevarnos a pensar: ¿qué pasaría si tuviéramos una clase
Method
cuyo comportamiento podríamos anular o controlar?Pues aquí está:
Y ahora:
InnocentClass().magic_method()
actuará como se esperaba. El método estará vinculado con elinnocent_self
parámetro aInnocentClass
, y con lamagic_self
instancia de MagicMethod. Raro eh? Es como tener 2 palabras clavethis1
ythis2
en lenguajes como Java y C #. Magia como esta permite que los frameworks hagan cosas que de otro modo serían mucho más detalladas.Nuevamente, no quiero comentar sobre la ética de estas cosas. Solo quería mostrar cosas que serían más difíciles de hacer sin una autorreferencia explícita.
fuente
OuterClass.this
para obtener el 'yo' de la clase externa, pero aún puede usarlothis
como referencia a sí misma; muy similar a lo que haces aquí en Python. Para mí no fue más difícil imaginar esto. ¿Tal vez depende de la competencia de uno en el idioma en cuestión?Something
, que a su vez se define dentro de otra implementación anónimaSomething
? En python, por supuesto, puede referirse a cualquiera de los ámbitos.this
. Las referencias implícitas son impossibru en Java.this
resultado. Por ejemploObject self1 = this;
(use Object, o algo menos genérico). Entonces, si usted tiene acceso a la variable en los alcances más altos, usted podría tener acceso aself1
,self2
, ...selfn
. Creo que estos deberían declararse definitivos o algo así, pero podría funcionar.Creo que la verdadera razón además de "The Zen of Python" es que las funciones son ciudadanos de primera clase en Python.
Lo que esencialmente los convierte en un Objeto. Ahora, el problema fundamental es si sus funciones también son objeto, entonces, en el paradigma orientado a objetos, ¿cómo enviaría mensajes a los objetos cuando los mensajes mismos son objetos?
Parece un problema de huevo de gallina, para reducir esta paradoja, la única forma posible es pasar un contexto de ejecución a los métodos o detectarlo. Pero dado que Python puede tener funciones anidadas, sería imposible hacerlo ya que el contexto de ejecución cambiaría para las funciones internas.
Esto significa que la única solución posible es pasar explícitamente 'self' (El contexto de ejecución).
Así que creo que es un problema de implementación, el Zen llegó mucho más tarde.
fuente
Creo que tiene que ver con PEP 227:
fuente
Como se explica en sí mismo en Python, desmitificado
Invocaciones
init () define tres parámetros pero acabamos de pasar dos (6 y 8). De manera similar, la distancia () requiere uno, pero se pasaron cero argumentos.
¿Por qué Python no se queja de esta discrepancia de número de argumento ?
fuente
También hay otra respuesta muy simple: según el zen de python , "explícito es mejor que implícito".
fuente