Instancias
Reflection Instance
Sección titulada «Reflection Instance»La clase ReflectionInstance es una utilidad de introspección diseñada para analizar objetos instanciados de Python en tiempo de ejecución. Proporciona una API completa para inspeccionar atributos, métodos, propiedades, metadatos y dependencias de cualquier instancia de una clase concreta definida por el usuario.
A diferencia de ReflectionConcrete, que opera sobre la definición de una clase (el tipo), ReflectionInstance trabaja directamente con un objeto ya instanciado, lo que permite acceder tanto a los atributos de la clase como a los atributos de instancia asignados en el constructor o durante la ejecución.
Importación
Sección titulada «Importación»from orionis.services.introspection.instances.reflection import ReflectionInstanceInicialización
Sección titulada «Inicialización»La clase recibe una instancia de un objeto como parámetro. Se valida que sea una instancia válida de una clase definida por el usuario, no un tipo, un built-in ni una clase abstracta.
from orionis.services.introspection.instances.reflection import ReflectionInstance
class UserService: """Service for managing users."""
public_attr: int
def __init__(self, x: int = 10) -> None: self.public_attr = x self._protected_attr = "prot" self.__private_attr = "priv"
def greet(self) -> str: return f"Hello, user #{self.public_attr}"
service = UserService(42)reflection = ReflectionInstance(service)Instancias rechazadas
Sección titulada «Instancias rechazadas»Los siguientes tipos de objetos no son aceptados y lanzarán excepciones:
# TypeError: una clase, no una instanciaReflectionInstance(UserService)
# TypeError: instancia de tipo built-inReflectionInstance(42)ReflectionInstance("hello")
# TypeError: NoneReflectionInstance(None)Contrato
Sección titulada «Contrato»La clase ReflectionInstance implementa el contrato IReflectionInstance, que define la interfaz completa para la introspección de instancias:
from orionis.services.introspection.instances.contracts.reflection import IReflectionInstanceIdentidad
Sección titulada «Identidad»getInstance
Sección titulada «getInstance»Retorna la instancia original del objeto que se está reflejando.
instance = reflection.getInstance()# Retorna el mismo objeto UserService pasado al constructorgetClass
Sección titulada «getClass»Retorna la clase del objeto instanciado.
cls = reflection.getClass()# <class 'UserService'>getClassName
Sección titulada «getClassName»Retorna el nombre de la clase como cadena de texto.
name = reflection.getClassName()# "UserService"getModuleName
Sección titulada «getModuleName»Retorna el nombre del módulo donde está definida la clase.
module = reflection.getModuleName()# "app.services.user_service"getModuleWithClassName
Sección titulada «getModuleWithClassName»Retorna el nombre completamente cualificado (módulo + clase).
fqn = reflection.getModuleWithClassName()# "app.services.user_service.UserService"Metadatos
Sección titulada «Metadatos»getDocstring
Sección titulada «getDocstring»Retorna el docstring de la clase de la instancia, o None si no tiene.
doc = reflection.getDocstring()# "Service for managing users."getBaseClasses
Sección titulada «getBaseClasses»Retorna una tupla con las clases base directas de la clase de la instancia.
bases = reflection.getBaseClasses()# (<class 'object'>,)getSourceCode
Sección titulada «getSourceCode»Retorna el código fuente de la clase completa o de un método específico. Retorna None si no está disponible.
# Código fuente de toda la clasesource = reflection.getSourceCode()
# Código fuente de un método específicomethod_source = reflection.getSourceCode("greet")getFile
Sección titulada «getFile»Retorna la ruta del archivo donde está definida la clase, o None si no es determinable.
path = reflection.getFile()# "/app/services/user_service.py"getAnnotations
Sección titulada «getAnnotations»Retorna un diccionario con las anotaciones de tipo de la clase. Resuelve automáticamente el name mangling en atributos privados.
annotations = reflection.getAnnotations()# {"public_attr": <class 'int'>}Atributos
Sección titulada «Atributos»ReflectionInstance clasifica los atributos de la instancia por nivel de visibilidad. A diferencia de ReflectionConcrete, aquí se inspeccionan los atributos asignados en la instancia (via vars(instance)), no los del diccionario de la clase.
getAttributes
Sección titulada «getAttributes»Retorna todos los atributos de la instancia, combinando públicos, protegidos, privados y dunder.
attrs = reflection.getAttributes()# {"public_attr": 42, "_protected_attr": "prot", "__private_attr": "priv", ...}getPublicAttributes
Sección titulada «getPublicAttributes»Retorna los atributos públicos de la instancia (sin prefijo de guión bajo).
public = reflection.getPublicAttributes()# {"public_attr": 42}getProtectedAttributes
Sección titulada «getProtectedAttributes»Retorna los atributos protegidos de la instancia (prefijo _).
protected = reflection.getProtectedAttributes()# {"_protected_attr": "prot"}getPrivateAttributes
Sección titulada «getPrivateAttributes»Retorna los atributos privados de la instancia (prefijo __). Los nombres se devuelven sin name mangling.
private = reflection.getPrivateAttributes()# {"__private_attr": "priv"}getDunderAttributes / getMagicAttributes
Sección titulada «getDunderAttributes / getMagicAttributes»Retorna los atributos dunder de la instancia. getMagicAttributes es un alias de getDunderAttributes.
dunder = reflection.getDunderAttributes()magic = reflection.getMagicAttributes() # EquivalentehasAttribute
Sección titulada «hasAttribute»Verifica si un atributo existe en la instancia.
reflection.hasAttribute("public_attr") # Truereflection.hasAttribute("missing") # FalsegetAttribute
Sección titulada «getAttribute»Obtiene el valor de un atributo, con soporte para valor por defecto.
value = reflection.getAttribute("public_attr") # 42value = reflection.getAttribute("missing", "default") # "default"setAttribute
Sección titulada «setAttribute»Establece un atributo en la instancia. Solo valores no invocables son aceptados.
reflection.setAttribute("public_attr", 100) # TrueValidaciones:
- El nombre debe ser un identificador Python válido
- No puede ser una palabra reservada
- El valor no puede ser un callable (lanza
TypeError)
removeAttribute
Sección titulada «removeAttribute»Elimina un atributo de la instancia. Lanza AttributeError si el atributo no existe.
reflection.removeAttribute("public_attr") # TruegetAttributeDocstring
Sección titulada «getAttributeDocstring»Retorna el docstring de un atributo específico, o None si no tiene. Lanza AttributeError si el atributo no existe.
doc = reflection.getAttributeDocstring("public_attr")Métodos
Sección titulada «Métodos»ReflectionInstance ofrece la misma API granular que ReflectionConcrete para inspeccionar métodos, organizada por visibilidad (público, protegido, privado), tipo (instancia, clase, estático, dunder) y naturaleza (síncrono, asíncrono).
Resumen de Métodos de Inspección
Sección titulada «Resumen de Métodos de Inspección»| Método | Descripción |
|---|---|
getMethods() | Todos los métodos (instancia + clase + estáticos) |
getPublicMethods() | Métodos de instancia públicos |
getPublicSyncMethods() | Públicos síncronos |
getPublicAsyncMethods() | Públicos asíncronos |
getProtectedMethods() | Métodos de instancia protegidos (_) |
getProtectedSyncMethods() | Protegidos síncronos |
getProtectedAsyncMethods() | Protegidos asíncronos |
getPrivateMethods() | Métodos de instancia privados (__) |
getPrivateSyncMethods() | Privados síncronos |
getPrivateAsyncMethods() | Privados asíncronos |
getPublicClassMethods() | Class methods públicos |
getPublicClassSyncMethods() | Class methods públicos síncronos |
getPublicClassAsyncMethods() | Class methods públicos asíncronos |
getProtectedClassMethods() | Class methods protegidos |
getProtectedClassSyncMethods() | Class methods protegidos síncronos |
getProtectedClassAsyncMethods() | Class methods protegidos asíncronos |
getPrivateClassMethods() | Class methods privados |
getPrivateClassSyncMethods() | Class methods privados síncronos |
getPrivateClassAsyncMethods() | Class methods privados asíncronos |
getPublicStaticMethods() | Static methods públicos |
getPublicStaticSyncMethods() | Static methods públicos síncronos |
getPublicStaticAsyncMethods() | Static methods públicos asíncronos |
getProtectedStaticMethods() | Static methods protegidos |
getProtectedStaticSyncMethods() | Static methods protegidos síncronos |
getProtectedStaticAsyncMethods() | Static methods protegidos asíncronos |
getPrivateStaticMethods() | Static methods privados |
getPrivateStaticSyncMethods() | Static methods privados síncronos |
getPrivateStaticAsyncMethods() | Static methods privados asíncronos |
getDunderMethods() | Métodos dunder (__init__, __repr__, etc.) |
getMagicMethods() | Alias de getDunderMethods() |
Todos los métodos retornan list[str] con los nombres encontrados. Los métodos privados se retornan sin name mangling.
Ejemplo de uso
Sección titulada «Ejemplo de uso»class MyService:
def process(self) -> str: return "done"
async def fetch(self) -> dict: return {}
def _validate(self) -> bool: return True
@classmethod def create(cls) -> "MyService": return cls()
@staticmethod def version() -> str: return "1.0"
reflection = ReflectionInstance(MyService())
reflection.getPublicMethods() # ["process", "fetch"]reflection.getPublicSyncMethods() # ["process"]reflection.getPublicAsyncMethods() # ["fetch"]reflection.getProtectedMethods() # ["_validate"]reflection.getPublicClassMethods() # ["create"]reflection.getPublicStaticMethods() # ["version"]hasMethod
Sección titulada «hasMethod»Verifica si un método existe en la instancia (busca en todas las categorías).
reflection.hasMethod("process") # Truereflection.hasMethod("missing") # FalsesetMethod
Sección titulada «setMethod»Agrega un nuevo método a la instancia. Lanza AttributeError si el nombre es inválido, y TypeError si el valor no es callable.
def new_method(self) -> str: return "new"
reflection.setMethod("new_method", new_method) # TrueremoveMethod
Sección titulada «removeMethod»Elimina un método de la clase de la instancia. Lanza AttributeError si el método no existe.
reflection.removeMethod("new_method")getMethodSignature
Sección titulada «getMethodSignature»Retorna el objeto inspect.Signature de un método específico. Lanza AttributeError si el método no existe o no es callable.
sig = reflection.getMethodSignature("process")# (self) -> strgetMethodDocstring
Sección titulada «getMethodDocstring»Retorna el docstring de un método, o None si no tiene. Lanza AttributeError si el método no existe.
doc = reflection.getMethodDocstring("process")# "Return the value of public_attr."Propiedades
Sección titulada «Propiedades»getProperties
Sección titulada «getProperties»Retorna los nombres de todas las propiedades definidas en la clase de la instancia.
class Config: @property def host(self) -> str: """Server hostname.""" return "localhost"
@property def _port(self) -> int: return 8080
reflection = ReflectionInstance(Config())reflection.getProperties() # ["host", "_port"]Propiedades por visibilidad
Sección titulada «Propiedades por visibilidad»| Método | Descripción |
|---|---|
getPublicProperties() | Propiedades públicas |
getProtectedProperties() | Propiedades protegidas (_) |
getPrivateProperties() | Propiedades privadas (__, sin mangling) |
getProperty
Sección titulada «getProperty»Obtiene el valor de una propiedad desde la instancia. Lanza AttributeError si no existe.
value = reflection.getProperty("host") # "localhost"getPropertySignature
Sección titulada «getPropertySignature»Retorna la firma del getter de una propiedad. Lanza AttributeError si no existe.
sig = reflection.getPropertySignature("host")# (self) -> strgetPropertyDocstring
Sección titulada «getPropertyDocstring»Retorna el docstring del getter de una propiedad, o cadena vacía si no tiene. Lanza AttributeError si no existe.
doc = reflection.getPropertyDocstring("host")# "Server hostname."Dependencias
Sección titulada «Dependencias»constructorSignature
Sección titulada «constructorSignature»Analiza las dependencias del constructor de la clase de la instancia, identificando parámetros resueltos (con valor por defecto o tipo primitivo) y no resueltos (que requieren inyección).
analysis = reflection.constructorSignature()# Signature(resolved=[...], unresolved=[...])methodSignature
Sección titulada «methodSignature»Analiza las dependencias de un método específico. Lanza AttributeError si el método no existe.
analysis = reflection.methodSignature("process")# Signature(resolved=[...], unresolved=[...])Caché Interno
Sección titulada «Caché Interno»ReflectionInstance implementa un sistema de caché en memoria que almacena los resultados de las operaciones de introspección para evitar recálculos costosos.
Protocolo de caché
Sección titulada «Protocolo de caché»La instancia soporta acceso tipo diccionario:
# Verificar existencia"key" in reflection
# Obtener valor (None si no existe)reflection["key"]
# Establecer valorreflection["key"] = value
# Eliminar entradadel reflection["key"]clearCache
Sección titulada «clearCache»Limpia todas las entradas del caché. Las siguientes llamadas a métodos recalcularán sus resultados.
reflection.clearCache()