subclases - python poo tutorial
¿Cómo obtener una lista completa de los métodos y atributos del objeto? (5)
Aquí hay una adición práctica a las respuestas de PierreBdR y Moe:
- para Python> = 2.6 y clases de nuevo estilo , dir () parece ser suficiente;
- para las clases de estilo antiguo , al menos podemos hacer lo que hace un módulo estándar para admitir la finalización de pestañas: además de dir()
, buscar __class__
- y luego ir por __bases__
:
# code borrowed from the rlcompleter module
# tested under Python 2.6 ( sys.version = ''2.6.5 (r265:79063, Apr 16 2010, 13:09:56) /n[GCC 4.4.3]'' )
# or: from rlcompleter import get_class_members
def get_class_members(klass):
ret = dir(klass)
if hasattr(klass,''__bases__''):
for base in klass.__bases__:
ret = ret + get_class_members(base)
return ret
def uniq( seq ):
""" the ''set()'' way ( use dict when there''s no set ) """
return list(set(seq))
def get_object_attrs( obj ):
# code borrowed from the rlcompleter module ( see the code for Completer::attr_matches() )
ret = dir( obj )
## if "__builtins__" in ret:
## ret.remove("__builtins__")
if hasattr( obj, ''__class__''):
ret.append(''__class__'')
ret.extend( get_class_members(obj.__class__) )
ret = uniq( ret )
return ret
(El código de prueba y la salida se eliminan por brevedad, pero básicamente para los objetos de estilo nuevo parece que tenemos los mismos resultados para get_object_attrs()
que para dir()
, y para las clases de estilo antiguo, la adición principal a la salida de dir()
parece para ser el atributo __class__
))
dir(re.compile(pattern))
no devuelve patrón como uno de los elementos de las listas. Es decir, devuelve:
[''__copy__'', ''__deepcopy__'', ''findall'', ''finditer'', ''match'', ''scanner'', ''search'', ''split'', ''sub'', ''subn'']
Según el manual, se supone que contiene
los nombres de los atributos del objeto, los nombres de los atributos de su clase y recursivamente los atributos de las clases base de su clase.
Dice también que
La lista no está necesariamente completa.
¿Hay alguna manera de obtener la lista completa ? Siempre asumí que dir devuelve una lista completa pero aparentemente no ...
También: ¿hay una manera de enumerar solo los atributos? ¿O sólo métodos?
Edición: esto es realmente un error en python -> supuestamente se corrige en la rama 3.0 (y quizás también en 2.6)
Así es como lo hago, útil para objetos personalizados simples a los que sigues agregando atributos:
Dado un objeto creado con obj = type("Obj",(object,),{})
, o simplemente:
class Obj: pass
obj = Obj()
Agrega algunos atributos:
obj.name = ''gary''
obj.age = 32
luego, para obtener un diccionario con solo los atributos personalizados:
{key: value for key, value in obj.__dict__.items() if not key.startswith("__")}
# {''name'': ''gary'', ''age'': 32}
Es por eso que el nuevo __dir__()
se ha agregado en Python 2.6
ver:
- http://docs.python.org/whatsnew/2.6.html#other-language-changes (desplácese hacia abajo un poco)
- http://bugs.python.org/issue1591665
Para la lista completa de atributos, la respuesta corta es: no. El problema es que los atributos se definen realmente como los argumentos aceptados por la getattr
incorporada getattr
. Como el usuario puede __getattr__
, permitiendo repentinamente cualquier tipo de atributo, no hay una forma genérica posible de generar esa lista. La función dir
devuelve las claves en el atributo __dict__
, es decir, todos los atributos accesibles si el método __getattr__
no se __getattr__
.
Para la segunda pregunta, realmente no tiene sentido. En realidad, los métodos son atributos exigibles, nada más. Sin embargo, podría filtrar los atributos que se pueden llamar y, utilizando el módulo de inspect
, determinar los métodos, métodos o funciones de clase.
Solo para complementar:
-
dir()
es la herramienta más poderosa / fundamental. [Más recomendado] - Las soluciones distintas de
dir()
simplemente proporcionan su forma de manejar la salida dedir()
.
Listado de atributos de 2do nivel o no, es importante que lo hagas tú mismo,
porque a veces es posible que desee tamizar vars internos con guiones bajos__
pero a veces es posible que necesite la__doc__
documentos__doc__
. -
__dir__()
ydir()
devuelve contenido idéntico. -
__dict__
ydir()
son diferentes.__dict__
devuelve contenido incompleto. IMPORTANTE :
__dir__()
a veces se puede sobrescribir con una función, valor o tipo, por el autor para cualquier propósito. Aquí hay un ejemplo:
//...//torchfun.py in traverse(self, mod, search_attributes) 445 if prefix in traversed_mod_names: 446 continue 447 names = dir(m) 448 for name in names: 449 obj = getattr(m,name)
TypeError : el descriptor__dir__
del''object''
objeto''object''
necesita un argumentoEl autor de pyTorch modificó el
__dir__()
a algo que requiere un argumento. Esta modificación hace quedir()
falle.- Si desea que un esquema confiable atraviese todos los atributos de un objeto, recuerde que cada estándar pythonic puede ser anulado y puede no ser válido, y cada convención puede no ser confiable.