IC # fazemos isso através da reflexão. Em Javascript é simples como:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Como fazer isso em Python?
@property
.
IC # fazemos isso através da reflexão. Em Javascript é simples como:
for(var propertyName in objectName)
var currentPropertyValue = objectName[propertyName];
Como fazer isso em Python?
@property
.
Respostas:
for property, value in vars(theObject).iteritems():
print property, ": ", value
Esteja ciente de que em alguns casos raros existe uma __slots__
propriedade, essas classes geralmente não têm __dict__
.
__setattr__()
. Definir valores diretamente no dicionário ignora o criador do objeto (e / ou o de seus pais). É bastante comum em python que mais coisas do que aparentam estar acontecendo em segundo plano durante a configuração de atributos (por exemplo, saneamento), o uso setattr()
garante que você não perca, ou seja forçado a lidar com eles explicitamente.
vars()
retorna apenas membros estáticos (ou seja, atributos e métodos de objetos registrados nos objetos __dict__
). Ele não retorna membros dinâmicos (isto é, atributos e métodos de objetos definidos dinamicamente pelo __getattr__()
método desse objeto ou magia semelhante). Com toda a probabilidade, sua file.ImplementationName
propriedade desejada é definida dinamicamente e, portanto, não está disponível para vars()
ou dir()
.
Veja inspect.getmembers(object[, predicate])
.
Retorne todos os membros de um objeto em uma lista de pares (nome, valor) classificados por nome. Se o argumento do predicado opcional for fornecido, apenas os membros para os quais o predicado retorna um valor verdadeiro serão incluídos.
>>> [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
vez de members
(existe alguma diferença entre os dois?). Eles poderiam ter corrigido o nome no Python 3.0 para torná-lo consistente.
__dict__
, desculpe.
inspect.getmembers()
encerra dir()
os benefícios colaterais (principalmente desprezíveis) de (A), incluindo atributos de classe dinâmica e atributos de metaclasse e (B) excluindo membros que não correspondem ao predicado passado. Bocejo, certo? inspect.getmembers()
é apropriado para bibliotecas de terceiros que oferecem suporte genericamente a todos os tipos de objetos possíveis. Para casos de uso padrão, no entanto, dir()
é absolutamente suficiente.
dir()
é a maneira simples. Veja aqui:
dir()
agradecer.
A __dict__
propriedade do objeto é um dicionário de todas as suas outras propriedades definidas. Observe que as classes Python podem substituir o getattr
e criar coisas que parecem propriedades, mas não estão presentes __dict__
. Há também as funções internas vars()
e dir()
que são diferentes de maneiras sutis. E __slots__
pode substituir __dict__
em algumas classes incomuns.
Objetos são complicados em Python. __dict__
é o lugar certo para começar a programação no estilo de reflexão. dir()
é o lugar para começar se você estiver navegando em um shell interativo.
print vars.__doc__
indica que With an argument, equivalent to object.__dict__
Então, quais seriam as diferenças sutis?
georg scholly versão mais curta
print vars(theObject)
Se você está procurando um reflexo de todas as propriedades, as respostas acima são ótimas.
Se você simplesmente deseja obter as chaves de um dicionário (que é diferente de um 'objeto' no Python), use
my_dict.keys()
my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys()
> ['abc', 'def', 'ghi']
obj['key']
vs. obj.property
) e a pergunta era sobre propriedades de objetos. Coloquei minha resposta aqui, porque há uma confusão fácil entre os dois.
Isso é totalmente coberto pelas outras respostas, mas vou explicitar. Um objeto pode ter atributos de classe e atributos de instância estáticos e dinâmicos.
class foo:
classy = 1
@property
def dyno(self):
return 1
def __init__(self):
self.stasis = 2
def fx(self):
return 3
stasis
é estático, dyno
dinâmico (cf. decorador de propriedades) e classy
é um atributo de classe. Se simplesmente fizermos __dict__
ou vars
conseguiremos apenas a estática.
o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}
Então, se quisermos, os outros __dict__
receberão tudo (e mais). Isso inclui métodos e atributos mágicos e métodos vinculados normais. Então, vamos evitar os seguintes:
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}
O type
chamado com um método decorado de propriedade (um atributo dinâmico) fornecerá o tipo do valor retornado, não method
. Para provar isso, vamos definir o json:
import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}
Se tivesse sido um método, teria colidido.
TL; DR. tente chamar extravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
todos os três, mas não métodos nem magia.