Je veux obtenir les attributs d'une classe, disons:
class MyClass():
a = "12"
b = "34"
def myfunc(self):
return self.a
using MyClass.__dict__
me donne une liste d'attributs et de fonctions, et même des fonctions comme __module__
et __doc__
. While MyClass().__dict__
me donne un dict vide à moins que je ne définisse explicitement une valeur d'attribut de cette instance.
Je veux juste les attributs, dans l'exemple ci-dessus, ceux-ci seraient: a
etb
python
python-2.7
class
attributes
Mohamed Khamis
la source
la source
Réponses:
Essayez le module d' inspection .
getmembers
et les divers tests devraient être utiles.ÉDITER:
Par exemple,
Maintenant, les méthodes et attributs spéciaux m'énervent - ils peuvent être traités de plusieurs façons, la plus simple étant simplement de filtrer en fonction du nom.
... et dont le plus compliqué peut inclure des vérifications de noms d'attributs spéciaux ou même des métaclasses;)
la source
attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
print [a[0] for a in attributes if '_' not in a[0]]
like_this
! Cela évitera également les attributs «privés», ce que vous avez peut-être fait exprès.inspect.getmembers(MyClass, ...
,MyClass
peut être remplacé par une classe ou un objet, et si vous avez besoin de la liste des valeurs de vos objets, vous devez remplacerMyClass
par votre variable objet (ouself
si vous mettez cette expression dans unedef __repr__()
méthode comme moi).i = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a))); z = [_[1] for _ in i if _[0] in '__dict__'][0]
et ensuite, il s'agit simplement d'obtenir les clés de z.la source
if not i.startswith('_')
au lieu deif i[:1] != '_'
?.__dict__.keys()
n'inclura pas les attributs du parent.myfunc
est un attribut deMyClass
. C'est comme ça que ça se trouve lorsque vous exécutez:Il recherche un attribut sur
myinstance
namedmyfunc
, n'en trouve pas, voit qu'ilmyinstance
s'agit d'une instance deMyClass
et le recherche là-haut.La liste complète des attributs pour
MyClass
est donc:(Notez que j'utilise dir simplement comme un moyen rapide et facile de lister les membres de la classe: il ne doit être utilisé que de manière exploratoire, pas dans le code de production)
Si vous ne souhaitez attributs particuliers, vous aurez besoin de filtrer cette liste en utilisant certains critères, parce que
__doc__
,__module__
etmyfunc
ne sont pas particulièrement en aucune façon, ils sont les attributs exactement de la même manièrea
etb
sont.Je n'ai jamais utilisé le module d'inspection mentionné par Matt et Borealid, mais à partir d'un bref lien, il semble qu'il y ait des tests pour vous aider à le faire, mais vous devrez écrire votre propre fonction de prédicat, car cela semble ce que vous voulez est à peu près les attributs qui ne passent pas le
isroutine
test et qui ne commencent et ne se terminent pas par deux traits de soulignement.Remarquez également: en utilisant
class MyClass():
Python 2.7, vous utilisez les classes à l'ancienne très obsolètes. À moins que vous ne le fassiez délibérément pour la compatibilité avec des bibliothèques extrêmement anciennes, vous devriez plutôt définir votre classe commeclass MyClass(object):
. Dans Python 3, il n'y a pas de classes «à l'ancienne», et ce comportement est le comportement par défaut. Cependant, l'utilisation de classes newstyle vous donnera beaucoup plus d'attributs définis automatiquement:la source
dir()
: " Parce que dir () est fourni principalement pour une utilisation pratique à une invite interactive, il essaie de fournir un ensemble intéressant de noms plus qu'il n'essaie de fournir un ensemble de noms défini de manière rigoureuse ou cohérente , et ses détails le comportement peut changer d'une version à l'autre . »(voir la documentation dedir()
).Obtenir uniquement les attributs de l' instance est facile.
Mais obtenir également les attributs de classe sans les fonctions est un peu plus délicat.
Attributs d'instance uniquement
Si vous n'avez qu'à lister les attributs d'instance, utilisez simplement
for attribute, value in my_instance
.__dict__
.items()
Attributs d'instance et de classe
Pour obtenir également les attributs de classe sans les fonctions, l'astuce est d'utiliser
callable()
.Mais les méthodes statiques ne le sont pas toujours
callable
!Par conséquent, au lieu d'utiliser,
callable(value)
utilisezcallable
(getattr
(MyClass, attribute))
Exemple
Remarque:
print_class_attributes()
devrait être mais pas dans cet exemple stupide et simple .@staticmethod
Résultat pour python2
Même résultat pour python3
la source
MyClass().__class__.__dict__
Cependant, le "droit" était de le faire via le module d'inspection .
la source
MyClass().__class__.__dict__
==MyClass.__dict__
MyClass().__class__.__dict__ != MyClass().__dict__
, mais yak n'inclut pas les parenthèses sur le côté droit, dans le cas où il / elle a raisonPour une instance de MyClass, telle que
utiliser
type(mc)
à la place deMyClass
dans la compréhension de la liste. Cependant, si l'on ajoute dynamiquement un attribut àmc
, tel quemc.c = "42"
, l'attribut n'apparaîtra pas lors de l'utilisationtype(mc)
dans cette stratégie. Il ne donne que les attributs de la classe d'origine.Pour obtenir le dictionnaire complet d'une instance de classe, vous devez COMBINER les dictionnaires de
type(mc).__dict__
etmc.__dict__
.la source
Je ne sais pas si quelque chose de similaire a déjà été fait ou non, mais j'ai créé une fonction de recherche d'attribut intéressante en utilisant vars (). vars () crée un dictionnaire des attributs d'une classe que vous lui passez.
Je développe une aventure textuelle assez massive en Python, ma classe Player a jusqu'à présent plus de 100 attributs. J'utilise ceci pour rechercher des attributs spécifiques que j'ai besoin de voir.
la source
Cela peut être fait sans inspecter, je suppose.
Suivez le cours suivant:
En regardant les membres avec leurs types:
... donne:
Donc, pour ne sortir que les variables, il vous suffit de filtrer les résultats par type et les noms ne commençant pas par «__». Par exemple
C'est tout.
Remarque: si vous utilisez Python 3, convertissez les itérateurs en listes.
Si vous voulez une manière plus robuste de le faire, utilisez inspect .
la source
Python 2 & 3, sans importations, filtrage des objets par leur adresse
Solutions en bref:
Renvoie dict {nom_attribut: valeur_attribut} , objets filtrés. c'est à dire
{'a': 1, 'b': (2, 2), 'c': [3, 3]}
Liste de retour [nom_attribut] , objets filtrés. c'est à dire
['a', 'b', 'c', 'd']
Liste de retour [valeur_attribut] , objets filtrés. c'est à dire
[1, (2, 2), [3, 3], {4: 4}]
Ne pas filtrer les objets
Suppression de la
if
condition. Revenir{'a': 1, 'c': [3, 3], 'b': (2, 2), 'e': <function <lambda> at 0x7fc8a870fd70>, 'd': {4: 4}, 'f': <object object at 0x7fc8abe130e0>}
Solution en long
Tant que l'implémentation par défaut de
__repr__
n'est pas remplacée, l'if
instruction retourneraTrue
si la représentation hexadécimale de l'emplacement en mémoire deval
est dans la__repr__
chaîne de retour.Concernant l'implémentation par défaut de,
__repr__
vous pourriez trouver utile cette réponse . En bref:Qui renvoie une chaîne comme:
L'emplacement en mémoire de chaque élément est obtenu via la
id()
méthode.Python Docs dit à propos de id ():
Essayez par vous-même
Production:
Remarque :
Testé avec Python
2.7.13
et Python3.5.3
En Python 2.x
.iteritems()
est préférable à.items()
la source
J'ai récemment eu besoin de trouver quelque chose de similaire à cette question, donc je voulais publier des informations de base qui pourraient être utiles à d'autres personnes confrontées à la même chose à l'avenir.
Voici comment cela fonctionne en Python (à partir de https://docs.python.org/3.5/reference/datamodel.html#the-standard-type-hierarchy ):
MyClass
est un objet de classe,MyClass()
est une instance de l'objet de classe. Une instance__dict__
contient uniquement des attributs et des méthodes spécifiques à cette instance (par exempleself.somethings
). Si un attribut ou une méthode fait partie d'une classe, il est dans la classe__dict__
. Lorsque vous le faitesMyClass().__dict__
, une instance deMyClass
est créée sans attribut ni méthode en plus des attributs de classe, donc le vide__dict__
Donc, si vous dites
print(MyClass().b)
, Python vérifie d'abord le dict de la nouvelle instanceMyClass().__dict__['b']
et ne parvient pas à le trouverb
. Il vérifie ensuite la classeMyClass.__dict__['b']
et trouveb
.C'est pourquoi vous avez besoin du
inspect
module pour émuler ce même processus de recherche.la source
Vous pouvez utiliser
dir()
dans une compréhension de liste pour obtenir les noms d'attributs:Utilisation
getattr()
pour obtenir les attributs eux-mêmes:la source
Ma solution pour obtenir tous les attributs (et non les méthodes) d'une classe (si la classe a une docstring correctement écrite avec les attributs clairement énoncés):
Cette pièce
cls.__dict__['__doc__']
extrait la docstring de la classe.la source
Pourquoi avez-vous besoin de lister les attributs? Il semble que sémantiquement votre classe est une collection. Dans ce cas, je recommande d'utiliser enum:
Listez vos attributs? Rien de plus simple que ça:
la source
Si vous voulez "obtenir" un attribut, il y a une réponse très simple , qui devrait être évidente: getattr
Cela fonctionne dandy à la fois en Python 2.7 et Python 3.x.
Si vous voulez une liste de ces éléments, vous devrez toujours utiliser inspect.
la source
deux fonctions:
utilisation:
la source
Voici ce que je veux.
Données de test
la source
Je sais que c'était il y a trois ans, mais pour ceux qui viendront se poser cette question à l'avenir, pour moi:
fonctionne très bien.
la source
attribute
est à l'avance.Vous pouvez utiliser
MyClass.__attrs__
. Il donne juste tous les attributs de cette classe. Rien de plus.la source