python - example - ¿Cuál es la relación entre__getattr__ y getattr?
repr python (3)
Sé que este código es correcto:
class A:
def __init__(self):
self.a = ''a''
def method(self):
print "method print"
a = A()
print getattr(a, ''a'', ''default'')
print getattr(a, ''b'', ''default'')
print getattr(a, ''method'', ''default'')
getattr(a, ''method'', ''default'')()
Y esto está mal:
# will __getattr__ affect the getattr?
class a(object):
def __getattr__(self,name):
return ''xxx''
print getattr(a)
Esto también es incorrecto:
a={''aa'':''aaaa''}
print getattr(a,''aa'')
¿Dónde debemos usar estas funciones ( __getattr__
y getattr
)?
La respuesta de Alex fue buena, pero te proporcionó un código de muestra ya que lo pediste :)
class foo:
def __init__(self):
self.a = "a"
def __getattr__(self, attribute):
return "You asked for %s, but I''m giving you default" % attribute
>>> bar = foo()
>>> bar.a
''a''
>>> bar.b
"You asked for b, but I''m giving you default"
>>> getattr(bar, "a")
''a''
>>> getattr(bar, "b")
"You asked for b, but I''m giving you default"
Así que en breve respuesta es
Tu usas
__getattr__
para definir cómo manejar los atributos que no se encuentran
y
getattr
para obtener los atributos
__getattr__()
es una función de método especial que puede definir. Cuando una búsqueda de miembros falla, esta función será llamada.
getattr()
es una función a la que puede llamar para intentar buscar un miembro. Si la búsqueda se realiza correctamente, obtiene el miembro (quizás un objeto de función de método o quizás un objeto de atributo de datos). getattr()
también puede devolver un valor predeterminado en el caso de que la búsqueda falle.
Si declara una función miembro __getattr__()
, puede hacer que tenga éxito a veces, o puede hacer que tenga éxito cada vez.
class A(object):
def __getattr__(self, name):
return "I pretend I have an attribute called ''%s''" % name
a = A()
print a.foo # prints "I pretend I have an attribute called ''foo''"
Python también tiene __getattribute__()
que siempre se __getattribute__()
en cada búsqueda. Es muy peligroso porque puede imposibilitar el acceso a los miembros normalmente.
class A(object):
def __init__(self, value):
self.v = value
def __getattribute__(self, name):
return "I pretend I have an attribute called ''%s''" % name
a = A(42)
print a.v # prints "I pretend I have an attribute called ''v''"
print a.__dict__["v"] # prints "I pretend I have an attribute called ''__dict__''"
Vaya, ahora es imposible acceder a av!
getattr
es una función incorporada que toma (al menos) dos argumentos: el objeto del cual se obtiene el atributo y el nombre de la cadena del atributo.
Si el nombre de la cadena es una constante, diga ''foo''
, getattr(obj, ''foo'')
es exactamente lo mismo que obj.foo
.
Por lo tanto, el caso de uso principal de la función getattr
es cuando no tiene el nombre del atributo como una constante, sino como una variable. Un segundo caso de uso importante es cuando le pasa tres argumentos, en lugar de solo dos: en ese caso, si el atributo está ausente del objeto, getattr
devuelve el tercer argumento, "predeterminado", en lugar de generar una excepción.
__getattr__
es un método especial, definido en una clase, que se invoca cuando se solicita algún atributo de una instancia de esa clase, y otras formas normales de suministrar ese atributo (a través de __dict__
, ranuras, propiedades, etc. de la instancia) fallaron . Puede definirlo, por ejemplo, cuando quiera delegar búsquedas de atributos no definidos de otra manera a otros objetos.
Entonces, su segundo ejemplo es incorrecto porque nunca se puede llamar al getattr
con un solo argumento.
El tercero falla porque el diccionario del que está intentando "obtener un atributo" no tiene ese atributo, tiene elementos , que por supuesto están totalmente separados de los atributos.