¿Por qué usar Python dos guiones para ciertas cosas?
-
27-09-2019 - |
Pregunta
Soy bastante nuevo en lenguajes de programación actuales, y Python es mi primera. Sé que mi camino alrededor de Linux un poco, lo suficiente para conseguir un trabajo de verano con ella (todavía estoy en la escuela secundaria), y en el trabajo, no tengo mucho tiempo libre que estoy usando para aprender Python.
Una cosa que me ha estado recibiendo sin embargo. ¿Qué es exactamente diferente en Python cuando se tiene expresiones tales como
x.__add__(y) <==> x+y
x.__getattribute__('foo') <==> x.foo
Sé lo hacen los métodos y esas cosas, y me sale lo que hacen, pero mi pregunta es: ¿Cómo son los métodos anteriores de subrayado doble diferentes de sus equivalentes más simples que buscan
P.S., No me importa recibir lecciones sobre la programación de la historia, de hecho, me resulta muy útil saber :) Si estos son aspectos principalmente históricos de Python, no dude en iniciar laberíntica.
Solución
Bueno, el poder para el programador es bueno, por lo que debe ser una forma de comportamiento de personalización. Al igual que la sobrecarga de operadores (__add__
, __div__
, __ge__
, ...), el acceso de atributo (__getattribute__
, __getattr__
(los dos son differnt), __delattr__
, ...), etc. En muchos casos, como los operadores, la sintaxis habitual mapas de 1: 1 con el método respectivo. En otros casos, existe un procedimiento especial que en algún momento implica una llamada al método correspondiente - por ejemplo, __getattr__
sólo se le llama si el objeto no tiene el atributo solicitado y __getattribute__
no se ejecute o AttributeError elevada. Y algunos de ellos son temas muy avanzados que le llevarán deeeeep en las entrañas del sistema de objetos y rara vez son necesarios. Así que no hay necesidad de aprender a todos, simplemente consultar la referencia cuando se necesita / quiere saber. Hablando de referencia, aquí es .
Otros consejos
Aquí es el creador de Python explicando que :
... en lugar de diseñar una nueva sintaxis para tipos especiales de los métodos de clase (por ejemplo, como inicializadores y destructores), I decidieron que estas características podrían ser manejado por simplemente requerir que el usuario para poner en práctica los métodos, con especial nombres tales como
__init__
,__del__
, y así sucesivamente. Esta convención fue tomado de C, donde los identificadores comenzando con guiones están reservados por el compilador y con frecuencia tienen especial significando (por ejemplo, como macros__FILE__
en el preprocesador C).
...
También utiliza esta técnica para permitir clases de usuarios para redefinir el comportamiento de los operadores de Python. Como anteriormente señalado, Python se implementa en C y utiliza tablas de punteros de función a implementar diversas capacidades de objetos incorporados (por ejemplo, “get atributo”,‘add’y‘llamada’). A permitir que estas capacidades para ser definidos en las clases definidas por el usuario, I mapeado el varios punteros de función especial a nombres de métodos tales como
__getattr__
,__add__
y__call__
. Hay un correspondencia directa entre éstos nombres y las tablas de la función punteros uno tiene que definir cuándo la implementación de nuevos objetos de Python en C.
Cuando se inicia un método con dos guiones (y no hay guiones al final), de Python nombre mangling reglas se aplican. Esta es una manera de simular vagamente la palabra clave private
de otros lenguajes orientados a objetos como C ++ y Java. (Aun así, el método sigue siendo técnicamente no es privado en la forma en que los métodos de Java y C ++ son privadas, pero es "más difícil de conseguir en" desde fuera de la instancia.)
Métodos con dos principales y dos finales se considera guiones para ser "incorporado" métodos, es decir, se usan por el intérprete y son generalmente las implementaciones concretas de operadores sobrecargados u otra funcionalidad integrada.
Se utilizan para especificar que el intérprete de Python debe utilizarlos en situaciones específicas.
por ejemplo., La función __add__
permite al operador +
de trabajo para las clases personalizadas. De lo contrario obtendrá algún tipo de error no definido cuando se intenta añadir.
Desde una perspectiva histórica, subrayado iniciales han sido a menudo utilizado como un método para indicar al programador que los nombres se han de considerar interno al módulo / / biblioteca paquete que define ellos. En lenguajes que no proporcionan un buen soporte para espacios de nombres privado, utilizando guiones es una convención para emular eso. En Python, cuando se define un método llamado '__foo__' el programador de mantenimiento sabe del nombre que algo especial está pasando que no está ocurriendo con un método llamado 'foo'. Si Python había elegido para su uso 'complemento' como el método interno a la sobrecarga de '+', entonces usted podría no tener una clase con un método 'Add' sin causar mucha confusión. Los guiones sirven como una señal de que algo de magia va a pasar.
Una serie de otras preguntas ahora están marcados como duplicados de esta pregunta, y al menos dos de ellos preguntar qué bien los métodos __spam__
se llaman, o lo que la convención se llama, y ??ninguna de las respuestas existentes cubren eso, así:
En realidad no hay nombre oficial para cualquiera.
Muchos desarrolladores no oficialmente los llaman "métodos dunder", de "doble guión".
Algunas personas utilizan el término "métodos mágicos", pero eso es algo ambiguo entre lo que significa métodos dunder, métodos especiales (véase más adelante), o algo en algún lugar entre los dos.
es un término oficial "atributos especiales", que se superpone de cerca, pero no del todo con los métodos dunder. El modelo de datos capítulo en la referencia nunca explica lo que es un atributo especial, pero la idea básica es que es al menos uno de los siguientes:
- Un atributo que se proporciona por el intérprete de sí o de su código de orden interna, como
__name__
en una función. - Un atributo que es parte de un protocolo implementado por el propio intérprete, como
__add__
para el operador+
, o__getitem__
para la indexación y rebanar. - Un atributo que se le permite al intérprete para buscar específicamente, haciendo caso omiso de la instancia y va derecho a la clase, al igual que
__add__
de nuevo.
La mayoría de los atributos especiales son métodos, pero no todos (por ejemplo, __name__
no lo es). Y la mayoría utiliza la convención "dunder", pero no todos (por ejemplo, el método next
de iteradores en Python 2.x).
Y mientras tanto, la mayoría de los métodos dunder son atributos especiales, pero no todos-en particular, que no es tan raro que stdlib o bibliotecas externas a querer definir sus propios protocolos que funcionan de la misma manera, al igual que el pickle
protocolo
[especulación] Python fue influenciado por Algol68 , Guido posiblemente utilizado Algol68 en el Universidad de Amsterdam donde tiene Algol68 un semejante " stropping régimen " llamada "afilar Cita". En Algol68 los operadores, tipos y palabras clave puede aparecerá en un tipo de letra diferente (por lo general ** negrita ??strong> **, o __ subrayado __), en los archivos de código fuente este tipo de letra se logra con comillas, por ejemplo, 'Abs' (donde se cita similar a citar en ' wikitext ')
Algol68 ? Python (Operadores asignan a funciones miembro)
- 'y' ? __and __
- 'o' ? __or __
- 'no' no ?
- 'entier' ? __trunc __
- 'SHL' ? __lshift __
- 'SHR' ? __rshift __
- 'UPB' ? __sizeof __
- 'larga' ? __long __
- 'int' ? __int __
- 'real' ? __float __
- 'formato' ? __format __
- 'repr' ? __repr __
- 'abs' ? __abs __
- 'menos' ? __neg __
- 'menos' ? __sub __
- 'más' ? __add __
- 'momentos' ? __mul __
- 'mod' ? __mod __
- 'div' ? __truediv __
- 'sobre' ? __div __
- 'arriba' ? __pow __
- 'im' ? imag
- 're' ? real
- 'conj' ? conjugado
En Algol68 estos se refiere como nombres negrita ??strong>, por ejemplo abs , pero "bajo-under-abs" __abs__ en Python.
Mis 2 centavos: ¢ Así que a veces - como un fantasma - al cortar y pegar las clases de Python en un wiki va a reencarnar mágicamente de Algol68 negrita ??strong> palabras clave. ¢