Traducción de métodos especiales

Chema Cortes py en ch3m4.org
Dom Ene 2 13:42:59 CET 2005


Joan Ordinas <jordinas <at> gmail.com> writes:

> 
> No he conseguido encontrar documentación que describa lo que creo es
> un comportamiento correcto de Python 2.3.3. El caso es que al ejecutar
> un método especial (__str__, por ejemplo) la documentación dice que,
> por ejemplo,
> 
>     str(o)
> 
> se traduce a
> 
>     o.__str__()
> 
> pero el caso es que se traduce a
> 
>     type(o).__str__(o)
> 
> o escrito de otra forma, para las nuevas clases
> 
>     o.__class__.__str__(o)
> 
> Esto sucede con todos los métodos especiales.
>>>
> ¿Alguien ha encontrado documentació que confirme esta impresión?

Creo recordar que alguna vez vi algo, tal vez una discursión en la lista
en inglés, pero no lo he podido localizar. Pero como bien se dice, para
qué quieres documentación si tienes los fuentes :-P

Aunque no son las fechas más propicias para concentrarse en ésto, he
conseguido algo de tiempo para mirarme los fuentes, y puedo darte algunas
conclusiones sobre este tema que me ha intrigado.

La ejecución de algunos métodos "especiales" como el __str__ se ejecutan
como si fueran siempre "slots", esto es, no buscan primero el atributo y
luego lo ejecutan, sino que lo hace en un sólo paso llamando al "tipo"
del objeto. Supongo que esto se debe a algún tipo de optimización, pero
me temo que habrá que preguntárselo a los desarrolladores de python.

La cosa es que se puede hacer un experimento para comprobarlo. Las
clases nuevas se distinguen de las antiguas en que tienen un método
adicional llamado '__getattribute__' que es quien "debería" traducir la
búsqueda de atributos y manejar los descriptores según unas reglas
fijadas.

Pues bien, probando:

class C(str):
  def __getattribute__(self, attr):
    print "Pedido atributo %s" % attr
    return str.__getattribute__(self, attr)

o=C()

Si haces str(s) verás que el método __getattribute__ nunca es llamado
como parece que sería obligado. Un comportamiento diferente a si haces
o.__str__() donde sí que se llama al __getattribute__

Creo que con esto quedan confirmadas tus "sospechas". ;-)

------------ próxima parte ------------
_______________________________________________
Python-es mailing list
Python-es en aditel.org
http://listas.aditel.org/listinfo/python-es


Más información sobre la lista de distribución Python-es