Quiero obtener los atributos de una clase, digamos:
class MyClass():
a = "12"
b = "34"
def myfunc(self):
return self.a
el uso MyClass.__dict__
me da una lista de atributos y funciones, e incluso funciones como __module__
y __doc__
. Mientras MyClass().__dict__
me da un dict vacío a menos que establezca explícitamente un valor de atributo de esa instancia.
Solo quiero los atributos, en el ejemplo anterior serían: a
yb
python
python-2.7
class
attributes
Mohamed Khamis
fuente
fuente
Respuestas:
Pruebe el módulo de inspección .
getmembers
y las diversas pruebas deberían ser útiles.EDITAR:
Por ejemplo,
Ahora, los métodos y atributos especiales me ponen de los nervios; se pueden tratar de varias maneras, la más fácil de las cuales es simplemente filtrar según el nombre.
... y el más complicado de los cuales puede incluir comprobaciones de nombres de atributos especiales o incluso metaclases;)
fuente
attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
print [a[0] for a in attributes if '_' not in a[0]]
like_this
! También evitará los atributos "privados", lo que podría haber hecho a propósito.inspect.getmembers(MyClass, ...
,MyClass
puede ser reemplazado por una clase o un objeto, y si necesitas la lista de los valores de tus objetos, debes reemplazarloMyClass
por tu variable de objeto (oself
si pones esta expresión en undef __repr__()
método como yo).i = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a))); z = [_[1] for _ in i if _[0] in '__dict__'][0]
y luego solo es cuestión de obtener las claves de z.fuente
if not i.startswith('_')
lugar deif i[:1] != '_'
?.__dict__.keys()
no incluiremos los atributos de los padres.myfunc
es un atributo deMyClass
. Así es como se encuentra cuando corres:Busca un atributo en
myinstance
namedmyfunc
, no encuentra uno, ve quemyinstance
es una instancia deMyClass
y lo busca allí.Entonces, la lista completa de atributos para
MyClass
es:(Tenga en cuenta que estoy usando dir solo como una forma rápida y fácil de enumerar los miembros de la clase: solo debe usarse de manera exploratoria, no en el código de producción)
Si sólo desea atributos particulares, tendrá que filtrar esta lista con algunos criterios, porque
__doc__
,__module__
ymyfunc
no son de ninguna manera especial, son atributos exactamente de la misma manera quea
yb
son.Nunca he usado el módulo de inspección al que se refieren Matt y Borealid, pero a partir de un breve enlace, parece que tiene pruebas para ayudarlo a hacer esto, pero deberá escribir su propia función de predicado, ya que parece lo que quiere son aproximadamente los atributos que no pasan la
isroutine
prueba y no comienzan ni terminan con dos guiones bajos.También tenga en cuenta: al usar
class MyClass():
Python 2.7, está usando las clases de estilo antiguo muy desactualizadas. A menos que lo esté haciendo deliberadamente por compatibilidad con bibliotecas extremadamente antiguas, debería definir su clase comoclass MyClass(object):
. En Python 3 no hay clases de "estilo antiguo" y este comportamiento es el predeterminado. Sin embargo, el uso de clases de estilo nuevo le proporcionará muchos más atributos definidos automáticamente:fuente
dir()
: " Debido a que dir () se proporciona principalmente como una conveniencia para su uso en un indicador interactivo, intenta proporcionar un conjunto interesante de nombres más de lo que intenta proporcionar un conjunto de nombres definido de manera rigurosa o coherente , y su comportamiento puede cambiar a través de comunicados . "(véase la documentación deldir()
).Obtener solo los atributos de la instancia es fácil.
Pero obtener también los atributos de clase sin las funciones es un poco más complicado.
Solo atributos de instancia
Si solo tiene que enumerar los atributos de instancia, use
for attribute, value in my_instance
.__dict__
.items()
Atributos de instancia y clase
Para obtener también los atributos de clase sin las funciones, el truco consiste en usar
callable()
.¡Pero los métodos estáticos no siempre lo
callable
son !Por lo tanto, en lugar de usar
callable(value)
usecallable
(getattr
(MyClass, attribute))
Ejemplo
Nota:
print_class_attributes()
debería ser, pero no en este ejemplo simple y estúpido .@staticmethod
Resultado para python2
Mismo resultado para python3
fuente
MyClass().__class__.__dict__
Sin embargo, el "derecho" era hacer esto a través del módulo de inspección .
fuente
MyClass().__class__.__dict__
==MyClass.__dict__
MyClass().__class__.__dict__ != MyClass().__dict__
, pero yak no incluye los paréntesis en el lado derecho, en el caso de que él / ella esté en lo correctoPara una instancia de MyClass, como
utilizar
type(mc)
en lugar deMyClass
en la comprensión de la lista. Sin embargo, si uno agrega dinámicamente un atributomc
, comomc.c = "42"
, el atributo no aparecerá cuando se usetype(mc)
en esta estrategia. Solo da los atributos de la clase original.Para obtener el diccionario completo para una instancia de clase, necesitaría COMBINAR los diccionarios de
type(mc).__dict__
ymc.__dict__
.fuente
No sé si se ha hecho algo similar a esta altura o no, pero hice una buena función de búsqueda de atributos usando vars (). vars () crea un diccionario de los atributos de una clase que pasa por él.
Estoy desarrollando una aventura de texto bastante masiva en Python, mi clase Player hasta ahora tiene más de 100 atributos. Utilizo esto para buscar atributos específicos que necesito ver.
fuente
Esto se puede hacer sin inspeccionar, supongo.
Toma la siguiente clase:
Mirando a los miembros junto con sus tipos:
... da:
Entonces, para generar solo las variables, solo tiene que filtrar los resultados por tipo y nombres que no comiencen con '__'. P.ej
Eso es.
Nota: si está utilizando Python 3, convierta los iteradores en listas.
Si desea una forma más sólida de hacerlo, use inspeccionar .
fuente
Python 2 y 3, sin importaciones, filtrando objetos por su dirección
Soluciones en resumen:
Devuelve dict {attribute_name: attribute_value} , objetos filtrados. es decir
{'a': 1, 'b': (2, 2), 'c': [3, 3]}
Lista de devolución [nombre_atributo] , objetos filtrados. es decir
['a', 'b', 'c', 'd']
Lista de devolución [atributo_valores] , objetos filtrados. es decir
[1, (2, 2), [3, 3], {4: 4}]
Sin filtrar objetos
Eliminando la
if
condición. Regreso{'a': 1, 'c': [3, 3], 'b': (2, 2), 'e': <function <lambda> at 0x7fc8a870fd70>, 'd': {4: 4}, 'f': <object object at 0x7fc8abe130e0>}
Solución en largo
Siempre que
__repr__
no se anule la implementación predeterminada de, laif
declaración regresaráTrue
si la representación hexadecimal de la ubicación en la memoria deval
está en la__repr__
cadena de retorno.Con respecto a la implementación predeterminada de
__repr__
, podría encontrar útil esta respuesta . En breve:Que devuelve una cadena como:
La ubicación en la memoria de cada elemento se obtiene mediante el
id()
método.Python Docs dice sobre id ():
Pruébelo usted mismo
Salida:
Nota :
Probado con Python
2.7.13
y Python3.5.3
En Python 2.x
.iteritems()
se prefiere a.items()
fuente
Recientemente, necesitaba resolver algo similar a esta pregunta, por lo que quería publicar información de fondo que podría ser útil para otras personas que enfrentan lo mismo en el futuro.
Así es como funciona en Python (de https://docs.python.org/3.5/reference/datamodel.html#the-standard-type-hierarchy ):
MyClass
es un objeto de clase,MyClass()
es una instancia del objeto de clase. Una instancia__dict__
solo contiene atributos y métodos específicos de esa instancia (pself.somethings
. Ej .). Si un atributo o método es parte de una clase, está en el de la clase__dict__
. Cuando lo haceMyClass().__dict__
, una instancia deMyClass
se crea sin atributos o métodos además de los atributos de clase, por lo que el vacío__dict__
Entonces, si dice
print(MyClass().b)
, Python primero verifica el dict de la nueva instanciaMyClass().__dict__['b']
y no encuentrab
. Luego verifica la claseMyClass.__dict__['b']
y encuentrab
.Por eso necesita el
inspect
módulo, para emular ese mismo proceso de búsqueda.fuente
Puede usar
dir()
en una lista de comprensión para obtener los nombres de los atributos:Úselo
getattr()
para obtener los atributos en sí mismos:fuente
Mi solución para obtener todos los atributos (no métodos) de una clase (si la clase tiene una cadena de documentación escrita correctamente que tiene los atributos claramente detallados):
Esta pieza
cls.__dict__['__doc__']
extrae la cadena de documentación de la clase.fuente
¿Por qué necesita enumerar los atributos? Parece que semánticamente tu clase es una colección. En estos casos, recomiendo usar enum:
Enumere sus atributos? Nada más fácil que esto:
fuente
Si desea "obtener" un atributo, hay una respuesta muy simple , que debería ser obvia: getattr
Funciona a la perfección tanto en Python 2.7 como en Python 3.x.
Si desea una lista de estos elementos, aún deberá utilizar inspeccionar.
fuente
dos funciones:
utilizar:
fuente
Lo siguiente es lo que quiero.
Datos de prueba
fuente
Sé que esto fue hace tres años, pero para aquellos que vendrán con esta pregunta en el futuro, para mí:
funciona bien.
fuente
attribute
es de antemano.Puede utilizar
MyClass.__attrs__
. Simplemente da todos los atributos de esa clase. Nada mas.fuente