J'ai récemment lu sur la getattr()
fonction . Le problème est que je n'arrive toujours pas à saisir l'idée de son utilisation. La seule chose que je comprends, getattr()
c'est getattr(li, "pop")
la même chose que d'appeler li.pop
.
Je ne comprenais pas quand le livre mentionnait comment vous l'utilisez pour obtenir une référence à une fonction sans connaître son nom jusqu'à l'exécution. C'est peut-être moi d'être un noob en programmation, en général. Quelqu'un pourrait-il faire la lumière sur le sujet? Quand et comment dois-je l'utiliser exactement?
Réponses:
getattr(object, 'x')
est complètement équivalent àobject.x
.Il n'y a que deux cas où cela
getattr
peut être utile.object.x
, car vous ne savez pas à l'avance quel attribut vous voulez (il provient d'une chaîne). Très utile pour la méta-programmation.object.y
soulèvera unAttributeError
s'il n'y a pasy
. Maisgetattr(object, 'y', 5)
reviendra5
.la source
Les objets en Python peuvent avoir des attributs - des attributs de données et des fonctions pour fonctionner avec ces (méthodes). En fait, chaque objet a des attributs intégrés.
Par exemple , vous avez un objet
person
, qui a plusieurs attributs:name
,gender
, etc.Vous accédez à ces attributs (que ce soit des méthodes ou des objets de données) écrit habituellement:
person.name
,person.gender
,person.the_method()
, etc.Mais que faire si vous ne connaissez pas le nom de l'attribut au moment où vous écrivez le programme? Par exemple, le nom de l'attribut est stocké dans une variable appelée
attr_name
.si
alors, au lieu d'écrire
tu peux écrire
Un peu de pratique:
getattr
augmenteraAttributeError
si l'attribut avec le nom donné n'existe pas dans l'objet:Mais vous pouvez passer une valeur par défaut comme troisième argument, qui sera retourné si cet attribut n'existe pas:
Vous pouvez utiliser
getattr
avecdir
pour parcourir tous les noms d'attributs et obtenir leurs valeurs:Une utilisation pratique pour cela serait de trouver toutes les méthodes dont les noms commencent par
test
et de les appeler .Similaire à
getattr
il y asetattr
qui vous permet de définir un attribut d'un objet ayant son nom:la source
getattr(..)
devrait être utilisé dans 2 scénarios: 1. lorsque le nom d'attribut est une valeur à l'intérieur d'une variable (par exemplegetattr(person, some_attr)
) et 2. lorsque nous devons utiliser le troisième argument positionnel pour la valeur par défaut (par exemplegetattr(person, 'age', 24)
). Si je vois un scénario commegetattr(person, 'age')
celui-ci, il me semble qu'il est identique àperson.age
ce qui m'amène à penser queperson.age
c'est plus Pythonic. Est-ce exact?Pour moi,
getattr
c'est plus facile à expliquer de cette façon:Il vous permet d'appeler des méthodes basées sur le contenu d'une chaîne au lieu de taper le nom de la méthode.
Par exemple, vous ne pouvez pas faire ceci:
parce que x n'est pas du type
builtin
, maisstr
. Cependant, vous POUVEZ faire ceci:Il vous permet de vous connecter dynamiquement avec des objets en fonction de votre entrée. Je l'ai trouvé utile lorsqu'il s'agit d'objets et de modules personnalisés.
la source
Un cas d'utilisation assez courant pour
getattr
mappage des données aux fonctions.Par exemple, dans un cadre Web comme Django ou Pylons,
getattr
il est facile de mapper l'URL d'une demande Web à la fonction qui va la gérer. Si vous regardez sous le capot du routage de Pylons, par exemple, vous verrez que (par défaut, au moins), il coupe l'URL d'une demande, comme:en "clients" et "liste". Il recherche ensuite une classe de contrôleur nommée
CustomerController
. En supposant qu'il trouve la classe, il crée une instance de la classe et l'utilise ensuitegetattr
pour obtenir salist
méthode. Il appelle ensuite cette méthode, en lui passant la demande comme argument.Une fois que vous avez compris cette idée, il devient très facile d'étendre les fonctionnalités d'une application Web: ajoutez simplement de nouvelles méthodes aux classes de contrôleur, puis créez des liens dans vos pages qui utilisent les URL appropriées pour ces méthodes. Tout cela est rendu possible par
getattr
.la source
Voici un exemple rapide et sale de la façon dont une classe peut déclencher différentes versions d'une méthode de sauvegarde en fonction du système d'exploitation sur lequel elle est exécutée
getattr()
.Utilisons maintenant cette classe dans un exemple:
la source
Outre toutes les réponses étonnantes ici, il existe un moyen d'utiliser
getattr
pour enregistrer de nombreuses lignes de code et le garder bien ajusté. Cette pensée est venue suite à la représentation épouvantable du code qui peut parfois être une nécessité.Scénario
Supposons que votre structure de répertoire soit la suivante:
Et, vous avez des fonctions pour obtenir des informations sur
Thor
,Iron Man
,Doctor Strange
ensuperheroes.py
. Vous écrivez très intelligemment les propriétés de chacun d'euxproperties.py
dans un compactdict
, puis y accédez.properties.py
Supposons maintenant que vous souhaitiez restituer les capacités de chacun d'eux à la demande
superheroes.py
. Donc, il y a des fonctions comme... et plus de fonctions renvoyant des valeurs différentes en fonction des touches et du super-héros.
Avec l'aide de
getattr
, vous pourriez faire quelque chose comme:Vous avez considérablement réduit le nombre de lignes de code, de fonctions et de répétition!
Oh et bien sûr, si vous avez des mauvais noms comme
properties_of_thor
pour les variables, ils peuvent être créés et accessibles en faisant simplementREMARQUE: pour ce problème particulier, il peut y avoir des moyens plus intelligents de gérer la situation, mais l'idée est de donner un aperçu de l'utilisation
getattr
aux bons endroits pour écrire du code plus propre.la source
la source
J'utilise parfois
getattr(..)
pour paresseusement initialiser des attributs d'importance secondaire juste avant qu'ils ne soient utilisés dans le code.Comparez les éléments suivants:
Pour ça:
L'avantage de la deuxième méthode est qu'elle
n_calls_to_plot
n'apparaît qu'à l'endroit du code où elle est utilisée. Ceci est bon pour la lisibilité, car (1) vous pouvez immédiatement voir quelle valeur il commence en lisant comment il est utilisé, (2) il n'introduit pas de distraction dans la__init__(..)
méthode, qui devrait idéalement concerner l'état conceptuel de la classe , plutôt qu'un certain compteur d'utilités qui n'est utilisé que par l'une des méthodes de la fonction pour des raisons techniques, telles que l'optimisation, et n'a rien à voir avec la signification de l'objet.la source
Très souvent, lorsque je crée un fichier XML à partir de données stockées dans une classe, je recevrais fréquemment des erreurs si l'attribut n'existait pas ou était de type
None
. Dans ce cas, mon problème n'était pas de savoir quel était le nom de l'attribut, comme indiqué dans votre question, mais plutôt des données ont-elles été stockées dans cet attribut.Si je faisais
hasattr
cela, cela reviendraitTrue
même si la valeur d'attribut était de typeNone
et cela entraînerait l'échec de maset
commande ElementTree .Si la valeur d'attribut était de type
None
, lagetattr
retournerait également, ce qui entraînerait l'échec de maset
commande ElementTree .J'utilise la méthode suivante pour m'occuper de ces cas maintenant:
C'est quand et comment j'utilise
getattr
.la source
Une autre utilisation de getattr () dans l'implémentation d'une instruction switch en Python. Il utilise à la fois la réflexion pour obtenir le type de cas.
la source
setattr ()
Nous utilisons setattr pour ajouter un attribut à notre instance de classe. Nous transmettons l'instance de classe, le nom d'attribut et la valeur.
getattr ()
Avec getattr nous ces valeurs
Par exemple
la source
Je pense que cet exemple est explicite. Il exécute la méthode du premier paramètre, dont le nom est donné dans le deuxième paramètre.
la source
Il clarifie également la page https://www.programiz.com/python-programming/methods/built-in/getattr
L'âge est: 23
L'âge est: 23
Le sexe est: masculin
AttributeError: l'objet "Personne" n'a pas d'attribut "sexe"
la source
J'ai essayé en Python2.7.17
Certains des collègues ont déjà répondu. Cependant, j'ai essayé d'appeler getattr (obj, 'set_value') et cela n'a pas exécuté la méthode set_value, j'ai donc changé pour getattr (obj, 'set_value') () -> Cela aide à invoquer la même chose.
Exemple de code:
Exemple 1:
la source