IC # lo facciamo attraverso la riflessione. In Javascript è semplice come:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Come farlo in Python?
@property
.
IC # lo facciamo attraverso la riflessione. In Javascript è semplice come:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Come farlo in Python?
@property
.
Risposte:
for property, value in vars(theObject).iteritems():
print property, ": ", value
Tieni presente che in alcuni rari casi esiste una __slots__
proprietà, tali classi spesso non ne hanno __dict__
.
__setattr__()
. L'impostazione dei valori direttamente sul dizionario ignora il setter dell'oggetto (e / o dei suoi genitori). È abbastanza comune in Python che durante l'impostazione degli attributi (ad es. Servizi igienico-sanitari) stiano accadendo più cose di quanto si pensi all'occhio, usando si setattr()
assicura che non si perda o si sia costretti a gestirle esplicitamente.
vars()
restituisce solo membri statici (ovvero attributi e metodi degli oggetti registrati con quelli di quell'oggetto __dict__
). Esso non ritorno utenti dinamici (cioè gli attributi degli oggetti e metodi definiti dinamicamente quell'oggetto __getattr__()
metodo o magia simile). Con ogni probabilità, la file.ImplementationName
proprietà desiderata viene definita in modo dinamico e quindi non disponibile per vars()
o dir()
.
Vedere inspect.getmembers(object[, predicate])
.
Restituisce tutti i membri di un oggetto in un elenco di coppie (nome, valore) ordinate per nome. Se viene fornito l'argomento predicato facoltativo, vengono inclusi solo i membri per i quali il predicato restituisce un valore vero.
>>> [name for name,thing in inspect.getmembers([])]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
'__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__',
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__','__reduce_ex__',
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__',
'__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']
>>>
attributes
invece di members
(c'è qualche differenza tra i due?). Avrebbero potuto correggere il nome in Python 3.0 per renderlo coerente.
__dict__
, scusa.
inspect.getmembers()
impacchi dir()
con (principalmente trascurabili) vantaggi collaterali di (A) compresi gli attributi di classe dinamica e attributi metaclasse e (B) , escluso l' non corrispondenti al predicato passato. Sbadiglio, vero? inspect.getmembers()
è appropriato per le librerie di terze parti che supportano genericamente tutti i possibili tipi di oggetti. Per i casi d'uso standard, tuttavia, è dir()
assolutamente sufficiente.
dir()
è il modo semplice. Vedere qui:
dir()
grazie.
La __dict__
proprietà dell'oggetto è un dizionario di tutte le altre proprietà definite. Nota che le classi Python possono sovrascrivere getattr
e creare cose che sembrano proprietà ma non ci sono __dict__
. Ci sono anche le funzioni integrate vars()
e dir()
che sono diverse in modo sottile. E __slots__
può sostituire __dict__
in alcune classi insolite.
Gli oggetti sono complicati in Python. __dict__
è il posto giusto da cui iniziare la programmazione in stile riflessivo. dir()
è il punto di partenza se stai hackerando in una shell interattiva.
print vars.__doc__
indica che With an argument, equivalent to object.__dict__
Quindi quali sarebbero le sottili differenze?
georg scholly versione più corta
print vars(theObject)
Se stai cercando il riflesso di tutte le proprietà, le risposte sopra sono ottime.
Se stai semplicemente cercando di ottenere le chiavi di un dizionario (che è diverso da un 'oggetto' in Python), usa
my_dict.keys()
my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys()
> ['abc', 'def', 'ghi']
obj['key']
vs. obj.property
) e la domanda riguardava le proprietà degli oggetti. Ho messo la mia risposta qui perché c'è una facile confusione tra i due.
Questo è totalmente coperto dalle altre risposte, ma lo renderò esplicito. Un oggetto può avere attributi di classe e attributi di istanza statici e dinamici.
class foo:
classy = 1
@property
def dyno(self):
return 1
def __init__(self):
self.stasis = 2
def fx(self):
return 3
stasis
è statico, dyno
dinamico (vedi decoratore di proprietà) ed classy
è un attributo di classe. Se lo facciamo semplicemente __dict__
o vars
avremo solo quello statico.
o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}
Quindi se vogliamo che gli altri __dict__
otterranno tutto (e altro). Ciò include metodi e attributi magici e metodi associati normali. Quindi evitiamo quelli:
d = {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
print(d) #{'stasis': 2, 'classy': 1, 'dyno': 1}
La type
chiamata con un metodo decorato con proprietà (un attributo dinamico) ti darà il tipo del valore restituito, no method
. Per dimostrarlo, Json lo stringe:
import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}
Se fosse stato un metodo si sarebbe schiantato.
TL; DR. prova a chiamare extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
tutti e tre, ma non metodi né magia.