str example espaƱol abs __getattr__ python getattr

python - example - El objeto ''super'' no llama a__getattr__



range python 3 (1)

De acuerdo con esto, super no permite llamadas implícitas de funciones "gancho" como __getattr__ . No estoy seguro de por qué se implementa de esta manera (probablemente hay una buena razón y las cosas ya son lo suficientemente confusas ya que el súper objeto tiene los __getattribute__ personalizados __getattribute__ y __get__ como están), pero parece que es así como están las cosas.

Edit: Esta publicación parece aclarar un poco las cosas. Parece que el problema es que la capa adicional de __getattribute__ indirecto causada por __getattribute__ se ignora cuando se __getattribute__ funciones implícitamente. Hacer foo.x es equivalente a

foo.__getattr__(x)

(Suponiendo que no se __getattribute__ definido el método __getattribute__ y que x no esté en foo.__dict__ ) Sin embargo, NO es equivalente a

foo.__getattribute__(''__getattr__'')(x)

Dado que super devuelve un objeto proxy, tiene una capa adicional de indirección que hace que las cosas fallen.

PD: el self.__dict__ comprobar en su función __getattr__ es completamente innecesario. __getattr__ solo se llama si el atributo no existe en su dict. (Use __getattribute__ si desea que siempre se llame, pero luego debe tener mucho cuidado, porque incluso algo simple como if name in self.__dict__ causará una recursión infinita.

Tengo un objeto envuelto dentro de otro. El "Wrapper" accede a los atributos del objeto "Wrapped" al reemplazar __getattr__ . Esto funciona bien hasta que necesito anular un atributo en una subclase y luego acceder al atributo desde la clase base usando super() .

Todavía puedo acceder al atributo directamente desde __getattr__ pero ¿por qué no funciona super() ?

class Wrapped(object): def __init__(self, value): self.value = value def hello_world(self): print ''hello world'', self.value class Wrapper(object): def __init__(self, obj): self.wrapped_obj = obj def __getattr__(self, name): if name in self.__dict__: return getattr(self, name) else: return getattr(self.wrapped_obj, name) class Subclass(Wrapper): def __init__(self, obj): super(Subclass, self).__init__(obj) def hello_world(self): # this works func = super(Subclass, self).__getattr__(''hello_world'')() # this doesn''t super(Subclass, self).hello_world() a = Wrapped(2) b = Subclass(a) b.hello_world()