web-dev-qa-db-fra.com

Comment lister tous les champs d'une classe (et aucune méthode)?

Supposons que o est un objet Python, et que je veux tous les champs de o, sans aucune méthode ni __stuff__. Comment cela peut-il être terminé?

J'ai essayé des choses comme:

[f for f in dir(o) if not callable(f)]

[f for f in dir(o) if not inspect.ismethod(f)]

mais ceux-ci renvoient la même chose que dir(o), probablement parce que dir donne une liste de chaînes. De plus, des choses comme __class__ Seraient renvoyées ici, même si cela fonctionne.

42
Eric Wilson

Vous pouvez l'obtenir via le __dict__, ou la fonction intégrée vars , qui n'est qu'un raccourci:

>>> class A(object):
...     foobar = 42
...     def __init__(self):
...         self.foo = 'baz'
...         self.bar = 3
...     def method(self, arg):
...         return True
...
>>> a = A()
>>> a.__dict__
{'foo': 'baz', 'bar': 3}
>>> vars(a)
{'foo': 'baz', 'bar': 3}

Il n'y a que des attributs de l'objet. Les méthodes et les attributs de classe ne sont pas présents.

54
Maxime Lorant

La réponse de base est "vous ne pouvez pas le faire de manière fiable". Voir cette question .

Vous pouvez obtenir une approximation avec [attr for attr in dir(obj) if attr[:2] + attr[-2:] != '____' and not callable(getattr(obj,attr))].

Cependant, vous ne devriez pas vous fier à cela, parce que :

Étant donné que dir() est fourni principalement à titre de commodité pour une invite interactive, il essaie de fournir un ensemble de noms intéressant plus qu'il ne tente de fournir un ensemble de noms défini de manière rigoureuse ou cohérente, et son comportement détaillé peut changer à travers les versions.

En d'autres termes, il n'existe aucun moyen canonique d'obtenir une liste de "tous les attributs d'un objet" (ou "toutes les méthodes d'un objet").

Si vous faites une sorte de programmation dynamique qui vous oblige à parcourir les champs inconnus d'un objet, la seule façon fiable de le faire est d'implémenter votre propre façon de garder une trace de ces champs. Par exemple, vous pouvez utiliser une convention de dénomination d'attribut, ou un objet spécial "champs", ou, tout simplement, un dictionnaire.

8
BrenBarn

Vous pouvez utiliser la méthode intégrée vars()

6
bvidal

Vous pouvez parcourir l'_ d'une instance__dict__attribuer et rechercher des éléments non liés à la méthode.
Par exemple:

CALLABLES = (types.FunctionType, types.MethodType)
for key, value in A().__dict__.items():
    if not isinstance(value, CALLABLES):
        print key

Sortie:

foo
bar

Vous pouvez le faire en une seule déclaration avec une compréhension de la liste:

print [key for key, value in A.__dict__.items()
            if not isinstance(value, CALLABLES)]

Qui imprimerait ['foo', 'bar'].

5
martineau

Cela devrait fonctionner pour les callables:

[f for f in dir(o) if not callable(getattr(o,f))]

Vous pourriez vous débarrasser du reste avec:

[f for f in dir(o) if not callable(getattr(o,f)) and not f.startswith('__')]
4
Benjamin Toueg