.
Je pense que les attributs des objets tels que les variables et les méthodes définies dans l'instruction class
sont généralement acquis par .
. Par exemple, supposons que vous définissiez la classe suivante.
python
class Foo:
def __init__(self):
self.foo = "foo"
self.bar = "bar"
Les attributs «foo» et «bar» de l'instance «foo» de «Foo» peuvent être obtenus avec «.».
python
>>> foo = Foo()
>>> foo.foo
'foo'
>>> foo.bar
'bar'
Ce comportement .
peut être personnalisé en utilisant les méthodes d'attributs spéciaux __getattr__
et __getattribute__
.
__getattr__
Si vous définissez __getattr__
, lorsque vous essayez d'obtenir un attribut dans .
, la recherche de nom normale est effectuée en premier, et si l'attribut spécifié n'est toujours pas trouvé, __getattr__
est appelé et la valeur renvoyée est utilisée. Renvoie comme cet attribut.
La classe suivante Foo
définit __getattr__
pour toujours renvoyer la variable membre foo
.
python
class Foo:
def __init__(self):
self.foo = "foo"
self.bar = "bar"
def __getattr__(self, name):
return self.foo
L'instance «foo» de «Foo» a une variable membre appelée «self.bar», donc «foo.bar» renvoie «self.bar», mais il n'y a pas de variable membre appelée «self.anything». Donc self .__ getattr__ (" n'importe quoi ")
est exécuté et self.foo
(c'est-à-dire la chaîne" foo "
) est renvoyée.
python
>>> foo = Foo()
>>> foo.foo
'foo'
>>> foo.bar
'bar'
>>> foo.anything
'foo'
__getattribute__
Si __getattribute__
est défini, cette méthode sera appelée chaque fois que vous essayez d'obtenir un attribut dans .
. Dans la définition de __getattribute__
, si vous essayez d'obtenir l'attribut de cet objet en utilisant .
, votre propre __getattribute__
sera appelé récursivement, donc pour éviter cela, la superclasse ʻobject Utilisez __getattribute__
de`.
python
class Bar:
def __init__(self):
self.foo = "foo"
self.bar = "bar"
def __getattribute__(self, name):
return object.__getattribute__(self, "foo")
Comme vous pouvez le voir à partir du résultat de l'exécution suivant, la bar
instance bar
a une variable membre appelée self.bar
, mais même si c'est bar.bar
, c'est __getattribute__
. self.foo` (c'est-à-dire la chaîne "" foo ") est renvoyée.
python
>>> bar = Bar()
>>> bar.foo
'foo'
>>> bar.bar
'foo'
>>> bar.anything
'foo'
getattr
et hasattr
Les fonctions intégrées getattr
et hasattr
sont basées sur l'acquisition d'attributs personnalisés avec __getattr__
et __hasattr__
. Donc, obtenir les attributs d'un objet avec getattr
équivaut à l'obtenir avec .
. Si vous vérifiez avec les instances Foo
et Bar
dans l'exemple ci-dessus, la sortie ressemblera à ceci.
python
>>> getattr(foo, "bar")
'bar'
>>> getattr(bar, "bar")
'foo'
Si __getattr__
ou __getattribute__
renvoie une valeur quel que soit l'attribut que vous spécifiez (c'est-à-dire que ʻAttribute Error ne se produit pas),
hasattrrenvoie toujours
True`.
python
>>> hasattr(foo, "anything")
True
>>> hasattr(bar, "anything")
True
Recommended Posts