privados - self en python
Listar atributos de un objeto (13)
¿Hay alguna forma de obtener una lista de atributos que existen en instancias de una clase?
class new_class():
def __init__(self, number):
self.multi = int(number) * 2
self.str = str(number)
a = new_class(2)
print('', ''.join(a.SOMETHING))
El resultado deseado es que se generará "multi, str". Quiero que esto vea los atributos actuales de varias partes de un script.
¿Para qué quieres esto? Puede ser difícil obtener la mejor respuesta sin conocer su intención exacta.
Casi siempre es mejor hacerlo manualmente si desea visualizar una instancia de su clase de una manera específica. Esto incluirá exactamente lo que desea y no incluirá lo que no desea, y el orden será predecible.
Si está buscando una forma de mostrar el contenido de una clase, formatee manualmente los atributos que le interesan y proporcione esto como el método
__str__
o__repr__
para su clase.Si desea conocer qué métodos existen para que un objeto entienda cómo funciona, use la
help
.help(a)
le mostrará un resultado formateado sobre la clase del objeto en función de sus documentos.dir
existe para obtener programáticamente todos los atributos de un objeto. (Acceder a__dict__
hace algo que__dict__
como el mismo pero que no utilizaría yo mismo.) Sin embargo, esto puede no incluir las cosas que desea y puede incluir cosas que no desea. No es confiable y las personas piensan que lo quieren mucho más a menudo que ellos.En una nota algo ortogonal, hay muy poco soporte para Python 3 en el momento actual. Si está interesado en escribir software real, va a querer cosas de terceros como numpy, lxml, Twisted, PIL o cualquier cantidad de frameworks web que aún no sean compatibles con Python 3 y no tengan planes en un futuro demasiado pronto. Las diferencias entre 2.6 y la rama 3.x son pequeñas, pero la diferencia en el soporte de la biblioteca es enorme.
A menudo se menciona que para enumerar una lista completa de atributos, debe usar dir()
. Sin embargo, tenga en cuenta que, contrariamente a la creencia popular, dir()
no saca todos los atributos. Por ejemplo, es posible que observe que __name__
puede estar ausente de la lista dir()
de una clase aunque pueda acceder a ella desde la clase misma. Del documento en dir()
( Python 2 , Python 3 ):
Debido a que dir () se proporciona principalmente como una conveniencia para su uso en un aviso interactivo, trata de proporcionar un conjunto interesante de nombres más de lo que intenta proporcionar un conjunto de nombres riguroso o consistentemente definido, y su comportamiento detallado puede cambiar a lo largo de las publicaciones. Por ejemplo, los atributos de metaclase no están en la lista de resultados cuando el argumento es una clase.
Una función como la siguiente tiende a ser más completa, aunque no hay garantía de integridad ya que la lista devuelta por dir()
puede verse afectada por muchos factores, como la implementación del __dir__()
o la personalización de __getattr__()
o __getattribute__()
en el clase o uno de sus padres. Vea los enlaces provistos para más detalles.
def dirmore(instance):
visible = dir(instance)
visible += [a for a in set(dir(type)).difference(visible)
if hasattr(instance, a)]
return sorted(visible)
Como está escrito antes de usar obj.__dict__
puede manejar casos comunes, pero algunas clases no tienen el atributo __dict__
y usan __slots__
(principalmente para la eficiencia de la memoria).
ejemplo para una forma más flexible de hacer esto:
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 salida de este código:
{''x'': 1, ''y'': 2}
{''x'': 1, ''y'': 2}
Nota 1:
Python es un lenguaje dinámico y siempre es mejor saber de qué clases intenta obtener los atributos, ya que incluso este código puede omitir algunos casos.
Nota 2:
este código genera solo variables de instancia, lo que significa que no se proporcionan las variables de clase. por ejemplo:
class A(object):
url = ''http://.com''
def __init__(self, path):
self.path = path
print(A(''/questions'').__dict__)
salidas de código:
{''path'': ''/questions''}
Este código no imprime el atributo de la clase url
y puede omitir los atributos de clase deseados.
A veces podemos pensar que un atributo es un miembro de instancia, pero no se muestra ni se mostrará con este ejemplo.
Consulte el script de Python Shell que se ha ejecutado en secuencia, aquí obtendrá los atributos de una clase en formato de cadena separados por comas.
>>> 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/>
Estoy usando Python 3.4
Consulte la siguiente ejecución de scripts de shell de Python en secuencia, le dará la solución desde la creación de la clase hasta la extracción de los nombres de campo de las instancias.
>>> 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'']
>>>
El módulo de inspect proporciona formas fáciles de inspeccionar un objeto:
El módulo de inspección proporciona varias funciones útiles para ayudar a obtener información sobre objetos en vivo, como módulos, clases, métodos, funciones, rastreo, objetos de marco y objetos de código.
Usando getmembers()
puedes ver todos los atributos de tu clase, junto con su valor. Para excluir atributos privados o protegidos, use .startswith(''_'')
. Para excluir métodos o funciones, use inspect.ismethod()
o 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)
Tenga en cuenta que ismethod()
se usa en el segundo elemento de i
ya que el primero es simplemente una cadena (su nombre).
Offtopic: utiliza CamelCase para los nombres de las clases.
Hay más de una forma de hacerlo:
#! /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) )
Cuando se ejecuta, este código produce:
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$
__attr__
da la lista de atributos de una instancia.
>>> import requests
>>> r=requests.get(''http://www.google.com'')
>>> r.__attrs__
[''_content'', ''status_code'', ''headers'', ''url'', ''history'', ''encoding'', ''reason'', ''cookies'', ''elapsed'', ''request'']
>>> r.url
''http://www.google.com/''
>>>
vars(obj)
devuelve los atributos de un objeto.
>>> '', ''.join(i for i in dir(a) if not i.startswith(''__''))
''multi, str''
Esto, por supuesto, imprimirá cualquier método o atributo en la definición de la clase. Puede excluir métodos "privados" cambiando i.startwith(''__'')
a i.startwith(''_'')
>>> 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''])
También puede encontrar útil a pprint .
attributes_list = [attribute for attribute in dir(obj) if attribute[0].islower()]
dir(instance)
# or
instance.__dict__
Luego puede probar qué tipo es con type()
o si es un método con callable()
.