493 votes

Liste des attributs d'un objet

Existe-t-il un moyen d'obtenir une liste d'attributs existant sur les instances d'une classe ?

class new_class():
    def __init__(self, number):
        self.multi = int(number) * 2
        self.str = str(number)

a = new_class(2)
print(', '.join(a.SOMETHING))

Le résultat souhaité est que "multi, str" soit affiché. Je veux que cela permette de voir les attributs actuels de différentes parties d'un script.

93 votes

Pratiquement tous les utilisateurs de Python nomment leurs classes de la manière suivante NewClass . Vous pouvez défier les attentes des gens en utilisant une convention de dénomination telle que new_class .

1 votes

Même s'il est interactif et ne peut pas être utilisé par des programmes, help() des aides fonctionnelles pour obtenir des informations sur les classes, les fonctions, les composants, les modules, etc.

2 votes

8voto

Lokesh kumar Points 79

Veuillez consulter le shell python script qui a été exécuté en séquence. Ici, vous obtiendrez les attributs d'une classe sous forme de chaîne de caractères séparée par une virgule.

>>> class new_class():
...     def __init__(self, number):
...         self.multi = int(number)*2
...         self.str = str(number)
... 
>>> a = new_class(4)
>>> ",".join(a.__dict__.keys())
'str,multi'<br/>

J'utilise python 3.4

6voto

Gershom Maes Points 208

En plus de ces réponses, j'inclurai une fonction (python 3) pour cracher pratiquement toute la structure de n'importe quelle valeur. Elle utilise dir pour établir la liste complète des noms de propriétés, puis utilise getattr pour chaque nom. Il affiche le type de chaque membre de la valeur et, si possible, le membre entier :

import json

def get_info(obj):

  type_name = type(obj).__name__
  print('Value is of type {}!'.format(type_name))
  prop_names = dir(obj)

  for prop_name in prop_names:
    prop_val = getattr(obj, prop_name)
    prop_val_type_name = type(prop_val).__name__
    print('{} has property "{}" of type "{}"'.format(type_name, prop_name, prop_val_type_name))

    try:
      val_as_str = json.dumps([ prop_val ], indent=2)[1:-1]
      print('  Here\'s the {} value: {}'.format(prop_name, val_as_str))
    except:
      pass

L'un ou l'autre des éléments suivants devrait permettre d'y voir plus clair :

get_info(None)
get_info('hello')

import numpy
get_info(numpy)
# ... etc.

2voto

Blessed Points 29

Obtenir les attributs d'un objet

class new_class():
    def __init__(self, number):
    self.multi = int(number) * 2
    self.str = str(number)

new_object = new_class(2)                
print(dir(new_object))                   #total list attributes of new_object
attr_value = new_object.__dict__         
print(attr_value)                        #Dictionary of attribute and value for new_class                   

for attr in attr_value:                  #attributes on  new_class
    print(attr)

Sortie

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__','__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'multi', 'str']

{'multi': 4, 'str': '2'}

multi
str

1voto

ShmulikA Points 1537

Comme écrit avant l'utilisation obj.__dict__ peut gérer les cas les plus courants, mais certaines classes n'ont pas les caractéristiques de la __dict__ et utiliser l'attribut __slots__ (principalement pour des raisons d'efficacité de la mémoire).

pour une manière plus souple de procéder :

class A(object):
    __slots__ = ('x', 'y', )
    def __init__(self, x, y):
        self.x = x
        self.y = y

class B(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

def get_object_attrs(obj):
    try:
        return obj.__dict__
    except AttributeError:
        return {attr: getattr(obj, attr) for attr in obj.__slots__}

a = A(1,2)
b = B(1,2)
assert not hasattr(a, '__dict__')

print(get_object_attrs(a))
print(get_object_attrs(b))

la sortie de ce code :

{'x': 1, 'y': 2}
{'x': 1, 'y': 2}

Note1 :
Python est un langage dynamique et il est toujours préférable de connaître les classes dont vous essayez d'obtenir les attributs, car même ce code peut manquer dans certains cas.

Note2 :
ce code ne produit que des variables d'instance, ce qui signifie que les variables de classe ne sont pas fournies, par exemple :

class A(object):
    url = 'http://stackoverflow.com'
    def __init__(self, path):
        self.path = path

print(A('/questions').__dict__)

les sorties de code :

{'path': '/questions'}

Ce code n'imprime pas le url et peut omettre les attributs de classe souhaités.
Parfois, nous pouvons penser qu'un attribut est un membre de l'instance, mais ce n'est pas le cas et nous ne le verrons pas dans cet exemple.

1voto

c z Points 1188
  • Utilisation __dict__ o vars ne fonctionne pas parce qu'il n'est pas pris en compte __slots__ .
  • Utilisation __dict__ y __slots__ ne fonctionne pas parce qu'il n'est pas pris en compte __slots__ des classes de base.
  • Utilisation dir ne fonctionne pas car il inclut les attributs de la classe, tels que les méthodes ou les propriétés, ainsi que les attributs de l'objet.
  • L'utilisation vars équivaut à utiliser __dict__ .

C'est le meilleur que j'ai :

from typing import Dict

def get_attrs( x : object ) -> Dict[str, object]:
    mro      = type( x ).mro()
    attrs    = { }
    has_dict = False
    sentinel = object()

    for klass in mro:
        for slot in getattr( klass, "__slots__", () ):
            v = getattr( x, slot, sentinel )

            if v is sentinel:
                continue

            if slot == "__dict__":
                assert not has_dict, "Multiple __dicts__?"
                attrs.update( v )
                has_dict = True
            else:
                attrs[slot] = v

    if not has_dict:
        attrs.update( getattr( x, "__dict__", { } ) )

    return attrs

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X