web-dev-qa-db-fra.com

Liste des attributs d'un objet

Existe-t-il un moyen de récupérer une liste d'attributs existant dans 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 sorti. Je veux que cela affiche les attributs actuels de différentes parties d'un script.

195
MadSc13ntist
>>> class new_class():
...   def __init__(self, number):
...     self.multi = int(number) * 2
...     self.str = str(number)
... 
>>> a = new_class(2)
>>> a.__dict__
{'multi': 4, 'str': '2'}
>>> a.__dict__.keys()
dict_keys(['multi', 'str'])

Vous pouvez également trouver pprint utile.

205
Roger Pate
dir(instance)
# or (same value)
instance.__dir__()
# or
instance.__dict__

Ensuite, vous pouvez tester quel type est avec type() ou si est une méthode avec callable().

124
mkotechno

vars(obj) renvoie les attributs d'un objet.

50
rohithpr
>>> ', '.join(i for i in dir(a) if not i.startswith('__'))
'multi, str'

Ceci imprimera bien sûr toutes les méthodes ou attributs de la définition de classe. Vous pouvez exclure les méthodes "privées" en remplaçant i.startwith('__') par i.startwith('_')

26
SilentGhost

Le module inspect fournit des moyens simples d'inspecter un objet: 

Le module inspecter fournit plusieurs fonctions utiles pour vous aider à obtenir informations sur les objets en direct tels que modules, classes, méthodes, fonctions, traces de retour, objets cadre et objets code. 


En utilisant getmembers(), vous pouvez voir tous les attributs de votre classe, ainsi que leur valeur. Pour exclure les attributs privés ou protégés, utilisez .startswith('_'). Pour exclure des méthodes ou des fonctions, utilisez inspect.ismethod() ou inspect.isfunction()

import inspect


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

    def func_1(self):
        pass


a = NewClass(2)

for i in inspect.getmembers(a):
    # Ignores anything starting with underscore 
    # (that is, private and protected attributes)
    if not i[0].startswith('_'):
        # Ignores methods
        if not inspect.ismethod(i[1]):
            print(i)

Notez que ismethod() est utilisé sur le deuxième élément de i car le premier est simplement une chaîne (son nom). 

Offtopic: Utilisez CamelCase pour les noms de classe.

21
Fermi paradox

Veuillez vous reporter au script shell Python exécuté en séquence. Vous obtiendrez ici les attributs d’une classe au format chaîne séparés 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

8
Lokesh kumar

Que voulez-vous cela? Il peut être difficile de vous obtenir la meilleure réponse sans connaître votre intention exacte.

  • Il est presque toujours préférable de le faire manuellement si vous souhaitez afficher une instance de votre classe de manière spécifique. Cela inclura exactement ce que vous voulez et non ce que vous ne voulez pas, et l'ordre sera prévisible. 

    Si vous recherchez un moyen d'afficher le contenu d'une classe, formatez manuellement les attributs qui vous intéressent et indiquez-le sous forme de méthode __str__ ou __repr__ pour votre classe.

  • Si vous voulez savoir quelles méthodes et quelles méthodes existent pour qu'un objet comprenne son fonctionnement, utilisez help. help(a) vous montrera une sortie formatée sur la classe de l'objet en fonction de ses docstrings.

  • dir existe pour obtenir par programme tous les attributs d'un objet. (Accéder à __dict__ fait quelque chose que je regrouperais de la même façon mais que je ne voudrais pas utiliser moi-même.) Toutefois, cela peut ne pas inclure les choses que vous voulez et peut inclure des choses que vous ne voulez pas. Ce n'est pas fiable et les gens pensent qu'ils le veulent beaucoup plus souvent qu'eux.

  • Sur une note quelque peu orthogonale, il n’ya que très peu de prise en charge de Python 3 à l’heure actuelle. Si vous êtes intéressé par l’écriture de logiciels réels, vous voudrez des éléments tiers tels que numpy, lxml, Twisted, PIL ou n’importe quel nombre de frameworks Web qui ne supportent pas encore Python 3 et n’ont pas prévu de le faire trop tôt. Les différences entre 2.6 et la branche 3.x sont faibles, mais la différence en ce qui concerne le support des bibliothèques est énorme.

8
Mike Graham

Il est souvent mentionné que pour lister une liste complète d'attributs, vous devriez utiliser dir(). Notez cependant que contrairement à la croyance populaire, dir() ne fait pas apparaître les attributs tous. Par exemple, vous remarquerez peut-être que __name__ pourrait ne pas figurer dans la liste dir() d'une classe, même si vous pouvez y accéder à partir de la classe elle-même. Extrait de la doc sur dir() ( Python 2 , Python 3 ):

Parce que dir () est fourni principalement à titre de commodité pour une utilisation avec un invite interactive, il essaie de fournir un ensemble de noms intéressant plus qu'il ne tente de fournir un ensemble défini de manière rigoureuse ou cohérente de noms, et son comportement détaillé peut changer d’une version à l’autre. Pour Par exemple, les attributs de métaclasse ne sont pas dans la liste des résultats lorsque l'argument est une classe.

Une fonction comme la suivante a tendance à être plus complète, bien que rien ne garantisse son exhaustivité, car la liste renvoyée par dir() peut être affectée par de nombreux facteurs, notamment la mise en œuvre de la méthode __dir__() ou la personnalisation de __getattr__() ou __getattribute__() par la classe ou l’un de ses parents. Voir les liens fournis pour plus de détails.

def dirmore(instance):
    visible = dir(instance)
    visible += [a for a in set(dir(type)).difference(visible)
                if hasattr(instance, a)]
    return sorted(visible)
8
Michael Ekoka

Toutes les réponses précédentes sont correctes, vous avez trois options pour ce que vous demandez 

1. dir ()

2. vars ()

3. _DICT_

>>> dir(a)
['__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']
>>> vars(a)
{'multi': 4, 'str': '2'}
>>> a.__dict__
{'multi': 4, 'str': '2'}
7
grepit

Il y a plus d'une façon de le faire:

#! /usr/bin/env python3
#
# This demonstrates how to pick the attiributes of an object

class C(object) :

  def __init__ (self, name="q" ):
    self.q = name
    self.m = "y?"

c = C()

print ( dir(c) )

Lorsqu'il est exécuté, ce code produit:

jeffs@jeff-desktop:~/skyset$ python3 attributes.py 
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',      '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'm', 'q']

jeffs@jeff-desktop:~/skyset$
7
user1928764

Vous pouvez utiliser dir(your_object) pour obtenir les attributs et getattr(your_object, your_object_attr) pour obtenir les valeurs.

utilisation:

for att in dir(your_object):
    print (att, getattr(your_object,att))

Ceci est particulièrement utile si votre objet n'a pas __dict__. Si ce n'est pas le cas, vous pouvez aussi essayer var (votre_objet)

4
Jason Angel

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
0
Blessed
attributes_list = [attribute for attribute in dir(obj) if attribute[0].islower()]
0
shammerw0w

Comme indiqué avant utilisation, obj.__dict__ peut gérer des cas courants, mais certaines classes ne possèdent pas l'attribut __dict__ et n'utilisent __slots__ (principalement pour optimiser l'efficacité de la mémoire).

exemple pour une manière plus résiliente de le faire:

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}

Note 1:
Python est un langage dynamique et il est toujours préférable de connaître les classes à partir desquelles vous essayez d'obtenir les attributs, car même ce code peut rater certains cas.

Note 2:
ce code n’affiche 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__)

sorties de code:

{'path': '/questions'}

Ce code n'imprime pas l'attribut de classe url et peut omettre des attributs de classe recherchés.
Parfois, nous pourrions penser qu'un attribut est un membre d'instance, mais il ne l'est pas et ne sera pas montré à l'aide de cet exemple.

0
ShmulikA

Veuillez vous reporter à l’exécution successive des scripts du shell Python suivants. La solution, de la création de la classe à l’extraction des noms de champs des instances, sera fournie.

>>> class Details:
...       def __init__(self,name,age):
...           self.name=name
...           self.age =age
...       def show_details(self):
...           if self.name:
...              print "Name : ",self.name
...           else:
...              print "Name : ","_"
...           if self.age:
...              if self.age>0:
...                 print "Age  : ",self.age
...              else:
...                 print "Age can't be -ve"
...           else:
...              print "Age  : ","_"
... 
>>> my_details = Details("Rishikesh",24)
>>> 
>>> print my_details
<__main__.Details instance at 0x10e2e77e8>
>>> 
>>> print my_details.name
Rishikesh
>>> print my_details.age
24
>>> 
>>> my_details.show_details()
Name :  Rishikesh
Age  :  24
>>> 
>>> person1 = Details("",34)
>>> person1.name
''
>>> person1.age
34
>>> person1.show_details
<bound method Details.show_details of <__main__.Details instance at 0x10e2e7758>>
>>> 
>>> person1.show_details()
Name :  _
Age  :  34
>>>
>>> person2 = Details("Rob Pike",0)
>>> person2.name
'Rob Pike'
>>> 
>>> person2.age
0
>>> 
>>> person2.show_details()
Name :  Rob Pike
Age  :  _
>>> 
>>> person3 = Details("Rob Pike",-45)
>>> 
>>> person3.name
'Rob Pike'
>>> 
>>> person3.age
-45
>>> 
>>> person3.show_details()
Name :  Rob Pike
Age can't be -ve
>>>
>>> person3.__dict__
{'age': -45, 'name': 'Rob Pike'}
>>>
>>> person3.__dict__.keys()
['age', 'name']
>>>
>>> person3.__dict__.values()
[-45, 'Rob Pike']
>>>
0
hygull