Notez que la meilleure pratique dans Python 2.7 est d'utiliser des classes de nouveau style (non nécessaires avec Python 3), c'est-à-dire
class Foo(object):
...
En outre, il existe une différence entre un «objet» et une «classe». Pour construire un dictionnaire à partir d'un objet arbitraire , il suffit d'utiliser __dict__
. Habituellement, vous déclarerez vos méthodes au niveau de la classe et vos attributs au niveau de l'instance, donc ça __dict__
devrait aller. Par exemple:
>>> class A(object):
... def __init__(self):
... self.b = 1
... self.c = 2
... def do_nothing(self):
... pass
...
>>> a = A()
>>> a.__dict__
{'c': 2, 'b': 1}
Une meilleure approche (suggérée par robert dans les commentaires) est la vars
fonction intégrée :
>>> vars(a)
{'c': 2, 'b': 1}
Alternativement, selon ce que vous voulez faire, il peut être intéressant d'hériter dict
. Ensuite, votre classe est déjà un dictionnaire, et si vous le souhaitez, vous pouvez remplacer getattr
et / ou setattr
appeler et définir le dict. Par exemple:
class Foo(dict):
def __init__(self):
pass
def __getattr__(self, attr):
return self[attr]
# etc...
__dict__
ne fonctionnera pas si l'objet utilise des slots (ou défini dans un module C).vars(a)
faire ça? Pour moi, il est préférable d'invoquer__dict__
directement le.__getattr__ = dict.__getitem__
reproduire exactement le comportement, alors vous voudriez aussi__setattr__ = dict.__setitem__
et__delattr__ = dict.__delitem__
pour la complétude.Au lieu de cela
x.__dict__
, c'est en fait plus pythonique à utiliservars(x)
.la source
MyClass(**my_dict)
, en supposant que vous avez défini un constructeur avec des paramètres qui reflètent les attributs de classe. Pas besoin d'accéder à des attributs privés ou de remplacer le dict.vars
fonction et introduire des fonctionnalités supplémentaires sans modifier l'objet lui-même.__slots__
.vars
, c'est-à-dire de renvoyer un équivalent de__dict__
pour les classes "slotted". Pour l'instant, il peut être émulé en ajoutant une__dict__
propriété qui retourne{x: getattr(self, x) for x in self.__slots__}
( je ne sais pas si cela affecte les performances ou le comportement de quelque manière que ce soit).La fonction
dir
intégrée vous donnera tous les attributs de l'objet, y compris des méthodes spéciales comme__str__
,__dict__
et tout un tas d'autres que vous ne voulez probablement pas. Mais vous pouvez faire quelque chose comme:Vous pouvez donc étendre cela pour ne renvoyer que des attributs de données et non des méthodes, en définissant votre
props
fonction comme ceci:la source
ismethod
n'attrape pas les fonctions. Exemple:inspect.ismethod(str.upper)
.inspect.isfunction
n'est pas beaucoup plus utile, cependant. Je ne sais pas comment aborder cela tout de suite.Je me suis installé avec une combinaison des deux réponses:
la source
staticmethod
? Ça ne l'est pascallable
.J'ai pensé prendre un peu de temps pour vous montrer comment traduire un objet à dicter via
dict(obj)
.La section clé de ce code est la
__iter__
fonction.Comme les commentaires l'expliquent, la première chose que nous faisons est de récupérer les éléments de classe et d'empêcher tout ce qui commence par «__».
Une fois que vous avez créé cela
dict
, vous pouvez utiliser laupdate
fonction dict et passer l'instance__dict__
.Ceux-ci vous donneront un dictionnaire complet de classe + instance de membres. Maintenant, il ne reste plus qu'à les parcourir et à générer des rendements.
De plus, si vous prévoyez de l'utiliser beaucoup, vous pouvez créer un
@iterable
décorateur de classe.la source
dict((x, y) for x, y in KpiRow.__dict__.items() if x[:2] != '__' and not callable(y))
- être le résoudra-t-il? Mais il pourrait toujours y avoir desstatic
méthodes :(Cela manque les attributs que l'objet hérite de sa classe. Par exemple,
hasattr (a, 'x') est vrai, mais 'x' n'apparaît pas dans un .__ dict__
la source
vars()
ne fonctionne pasdir
est la solution dans ce cas. Voir l'autre réponse à ce sujet.Réponse tardive mais prévue pour l'exhaustivité et l'avantage des googleurs:
Cela n'affichera pas les méthodes définies dans la classe, mais il affichera toujours les champs incluant ceux assignés aux lambdas ou ceux qui commencent par un double soulignement.
la source
Je pense que la façon la plus simple est de créer un attribut getitem pour la classe. Si vous devez écrire sur l'objet, vous pouvez créer un setattr personnalisé . Voici un exemple pour getitem :
dict génère les attributs des objets dans un dictionnaire et l'objet dictionnaire peut être utilisé pour obtenir l'élément dont vous avez besoin.
la source
Un inconvénient de l'utilisation
__dict__
est qu'elle est peu profonde; il ne convertira aucune sous-classe en dictionnaires.Si vous utilisez Python3.5 ou supérieur, vous pouvez utiliser
jsons
:la source
Si vous souhaitez répertorier une partie de vos attributs, remplacez
__dict__
:Cela aide beaucoup si vous
instance
obtenez des données de bloc volumineuses et que vous souhaitez pousserd
vers Redis comme la file d'attente de messages.la source
__dict__
est un attribut, pas une méthode, donc cet exemple change l'interface (c'est-à-dire que vous devez l'appeler comme appelable), donc il ne la remplace pas.PYTHON 3:
Vous pouvez maintenant utiliser le code ci-dessus dans votre propre classe:
la source
vars()
est génial, mais ne fonctionne pas pour les objets imbriqués d'objetsConvertir un objet imbriqué d'objets en dict:
la source