J'ai un objet python avec plusieurs attributs et méthodes. Je veux parcourir les attributs d'objet.
class my_python_obj(object):
attr1='a'
attr2='b'
attr3='c'
def method1(self, etc, etc):
#Statements
Je veux générer un dictionnaire contenant tous les attributs des objets et leurs valeurs actuelles, mais je veux le faire de manière dynamique (donc si plus tard j'ajoute un autre attribut, je n'ai pas à me souvenir de mettre à jour ma fonction également).
En php, les variables peuvent être utilisées comme clés, mais les objets en python sont insuscriptibles et si j'utilise la notation par points pour cela, cela crée un nouvel attribut avec le nom de ma var, ce qui n'est pas mon intention.
Juste pour clarifier les choses:
def to_dict(self):
'''this is what I already have'''
d={}
d["attr1"]= self.attr1
d["attr2"]= self.attr2
d["attr3"]= self.attr3
return d
·
def to_dict(self):
'''this is what I want to do'''
d={}
for v in my_python_obj.attributes:
d[v] = self.v
return d
Mise à jour: Avec les attributs, je veux dire uniquement les variables de cet objet, pas les méthodes.
python
oop
attributes
iteration
Pablo Mescher
la source
la source
predicate
argument optionnel pour passer un appelable qui filtrerait les fonctions (liées?) (qui se débarrasserait des méthodes).Réponses:
En supposant que vous ayez un cours tel que
l'appel
dir
de l'objet vous rend tous les attributs de cet objet, y compris les attributs spéciaux python. Bien que certains attributs d'objet soient appelables, tels que les méthodes.Vous pouvez toujours filtrer les méthodes spéciales en utilisant une compréhension de liste.
ou si vous préférez la carte / les filtres.
Si vous souhaitez filtrer les méthodes, vous pouvez utiliser la fonction intégrée
callable
comme vérification.Vous pouvez également inspecter la différence entre votre classe et son objet d'instance en utilisant.
la source
callable
outypes.MethodType
. Que se passe-t-il si j'ajoute un attribut appelé "_foo" qui stocke un résultat intermédiaire ou une structure de données interne? Que se passe-t-il si j'ajoute simplement un attribut à la classe de manière inoffensivename
, disons, et maintenant, tout d'un coup, il est inclus._foo
etname
parce qu'ils sont maintenant des attributs de l'objet. Si vous ne souhaitez pas les inclure, vous pouvez les exclure de la condition de compréhension de liste. Le code ci-dessus est un idiome python commun et un moyen populaire d'introspection des objets python.dir()
ne "ment" que lorsqu'il est passé des métaclasses (un cas extrême) ou des classes avec des attributs décorés par@DynamicClassAttribute
(un autre cas extrême). Dans les deux cas, l'appel dudirs()
wrapperinspect.getmembers()
résout ce problème. Pour les objets standard, cependant, l'approche de compréhension de liste de cette solution filtrant les non-appelables suffit absolument . Que certains pythonistes qualifient cela de "mauvaise idée" me déroute, mais ... à chacun le leur, je suppose?en général, mettez une
__iter__
méthode dans votre classe et parcourez les attributs d'objet ou mettez cette classe mixin dans votre classe.Ta classe:
la source
one
ettwo
est défini aprèsyc = YourClass()
. La question porte sur la boucle à travers l'attris existanteYourClass()
. En outre, l'héritage de laIterMixin
classe peut ne pas toujours être disponible en tant que solution.vars(yc)
donne le même résultat sans avoir à hériter d'une autre classe.vars(yc)
est presque le même, mais le dictionnaire qu'il vous renvoie est le propre de l'instance__dict__
, donc sa modification sera répercutée sur l'instance. Cela peut entraîner des problèmes si vous ne faites pas attention, donc la méthode ci-dessus peut parfois être meilleure (bien que copier le dictionnaire soit probablement plus facile). Notez également que bien que le dictionnaire renvoyé ci-dessus ne soit pas celui de l'instance__dict__
, les valeurs sont les mêmes, donc la modification de toute valeur mutable sera toujours reflétée dans les attributs de l'instance.Comme mentionné dans certaines réponses / commentaires déjà, les objets Python stockent déjà un dictionnaire de leurs attributs (les méthodes ne sont pas incluses). Cela peut être consulté en tant que
__dict__
, mais la meilleure façon est d'utiliservars
(la sortie est la même, cependant). Notez que la modification de ce dictionnaire modifiera les attributs de l'instance! Cela peut être utile, mais cela signifie également que vous devez faire attention à la façon dont vous utilisez ce dictionnaire. Voici un exemple rapide:L'utilisation
dir(a)
est une approche étrange, sinon carrément mauvaise, de ce problème. C'est bien si vous aviez vraiment besoin d'itérer sur tous les attributs et méthodes de la classe (y compris les méthodes spéciales comme__init__
). Cependant, cela ne semble pas être ce que vous voulez, et même la réponse acceptée y parvient mal en appliquant un filtrage fragile pour essayer de supprimer les méthodes et ne laisser que les attributs; vous pouvez voir comment cela échouerait pour la classeA
définie ci-dessus.(l'utilisation
__dict__
a été faite dans quelques réponses, mais elles définissent toutes des méthodes inutiles au lieu de l'utiliser directement. Seul un commentaire suggère d'utiliservars
).la source
a.b
une classe personnaliséeB
alorsvars(a)["b"] is a.b
, comme on peut s'y attendre; rien d'autre n'aurait vraiment de sens (pensez à dua.b
sucre syntaxique poura.__dict__["b"]
). Si vous avezd = vars(a)
et appelez,repr(d)
il appellerarepr(d["b"])
dans le cadre du retour de sa propre chaîne de reprogrammation, car seule la classeB
sait vraiment comment elle doit être représentée sous forme de chaîne.Les objets en python stockent leurs attributs (y compris les fonctions) dans un dict appelé
__dict__
. Vous pouvez (mais généralement pas) l'utiliser pour accéder directement aux attributs. Si vous voulez juste une liste, vous pouvez également appelerdir(obj)
, qui retourne un itérable avec tous les noms d'attribut, que vous pouvez ensuite passergetattr
.Cependant, avoir besoin de faire quoi que ce soit avec les noms des variables est généralement une mauvaise conception. Pourquoi ne pas les conserver dans une collection?
Vous pouvez ensuite parcourir les clés avec
for key in obj.special_values:
la source
alors appelez-le simplement comme un itérable
la source
La bonne réponse à cela est que vous ne devriez pas. Si vous voulez ce type de chose, utilisez simplement un dict ou vous devrez ajouter explicitement des attributs à certains conteneurs. Vous pouvez automatiser cela en vous renseignant sur les décorateurs.
En particulier, en passant, méthode1 dans votre exemple est tout aussi bonne d'un attribut.
la source
Pour python 3.6
la source
Pour tous les fanatiques pythoniens, je suis sûr que Johan Cleeze approuverait votre dogmatisme;). Je laisse cette réponse continuer à la démériter. Cela me rend en fait plus confidentiel. Laissez un commentaire vous les poulets!
Pour python 3.6
la source