Clases Concretas
Reflection Concrete
Sección titulada «Reflection Concrete»La clase ReflectionConcrete es una utilidad avanzada de introspección diseñada para analizar clases concretas de Python en tiempo de ejecución. Proporciona una API completa para inspeccionar atributos, métodos, propiedades, metadatos y dependencias de cualquier clase concreta (no abstracta) registrada en el framework Orionis.
A diferencia de ReflectionAbstract, que opera sobre clases base abstractas, ReflectionConcrete se enfoca exclusivamente en clases instanciables que tienen una implementación completa. Esto la convierte en la herramienta ideal para el análisis de servicios, controladores, modelos y cualquier componente concreto del framework.
Importación
Sección titulada «Importación»from orionis.services.introspection.concretes.reflection import ReflectionConcreteInicialización
Sección titulada «Inicialización»La clase ReflectionConcrete recibe como parámetro una clase concreta válida. Si la clase proporcionada es abstracta, un tipo primitivo, un built-in o no es una clase, se lanzará un TypeError.
from orionis.services.introspection.concretes.reflection import ReflectionConcrete
class UserService: """Service for managing users."""
active: bool = True
def __init__(self, name: str = "default") -> None: self.name = name
def greet(self) -> str: return f"Hello, {self.name}"
reflection = ReflectionConcrete(UserService)Si intentas pasar un tipo no válido:
from abc import ABC, abstractmethod
class MyContract(ABC): @abstractmethod def execute(self) -> str: ...
# TypeError: clase abstractaReflectionConcrete(MyContract)
# TypeError: no es una claseReflectionConcrete(42)
# TypeError: built-inReflectionConcrete(len)Contrato
Sección titulada «Contrato»La clase ReflectionConcrete implementa el contrato IReflectionConcrete, que define la interfaz completa para la introspección de clases concretas:
from orionis.services.introspection.concretes.contracts.reflection import IReflectionConcreteIdentidad de la Clase
Sección titulada «Identidad de la Clase»Estos métodos permiten obtener información básica de identificación sobre la clase reflejada.
getClass
Sección titulada «getClass»Retorna el tipo (la clase) asociado a la instancia de reflexión.
cls = reflection.getClass()# <class 'UserService'>getClassName
Sección titulada «getClassName»Retorna el nombre simple 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, o None si no tiene.
doc = reflection.getDocstring()# "Service for managing users."getBaseClasses
Sección titulada «getBaseClasses»Retorna la lista de clases base directas en el orden de resolución.
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 el código 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")Para métodos privados con name mangling, utiliza el nombre sin prefijo:
source = reflection.getSourceCode("__private_method")getFile
Sección titulada «getFile»Retorna la ruta absoluta del archivo donde está definida la clase.
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()# {"active": <class 'bool'>}Atributos
Sección titulada «Atributos»ReflectionConcrete clasifica los atributos de la clase por nivel de visibilidad, excluyendo métodos, propiedades, staticmethod y classmethod.
getAttributes
Sección titulada «getAttributes»Retorna todos los atributos de la clase, combinando públicos, protegidos, privados y dunder.
attrs = reflection.getAttributes()getPublicAttributes
Sección titulada «getPublicAttributes»Retorna los atributos públicos (sin prefijo de guión bajo).
public = reflection.getPublicAttributes()# {"active": True}getProtectedAttributes
Sección titulada «getProtectedAttributes»Retorna los atributos protegidos (prefijo _).
protected = reflection.getProtectedAttributes()# {"_internal_flag": False}getPrivateAttributes
Sección titulada «getPrivateAttributes»Retorna los atributos privados (prefijo __). Los nombres se devuelven sin name mangling.
private = reflection.getPrivateAttributes()# {"__secret": "value"} — no "_ClassName__secret"getDunderAttributes / getMagicAttributes
Sección titulada «getDunderAttributes / getMagicAttributes»Retorna los atributos dunder personalizados de la clase, excluyendo los estándar de Python (__dict__, __module__, __doc__, etc.). getMagicAttributes es un alias de getDunderAttributes.
dunder = reflection.getDunderAttributes()magic = reflection.getMagicAttributes() # EquivalentehasAttribute
Sección titulada «hasAttribute»Verifica si un atributo existe en la clase.
reflection.hasAttribute("active") # Truereflection.hasAttribute("missing") # FalsegetAttribute
Sección titulada «getAttribute»Obtiene el valor de un atributo, con soporte para valor por defecto.
value = reflection.getAttribute("active") # Truevalue = reflection.getAttribute("missing", "N/A") # "N/A"setAttribute
Sección titulada «setAttribute»Establece un atributo en la clase. Solo valores no invocables son aceptados; para agregar métodos, utiliza setMethod.
reflection.setAttribute("active", False) # 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 clase. Lanza ValueError si el atributo no existe.
reflection.removeAttribute("active") # TrueMétodos
Sección titulada «Métodos»ReflectionConcrete ofrece una API granular para inspeccionar métodos organizados por tres ejes: 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 de los métodos 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 = ReflectionConcrete(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 clase (busca en todas las categorías).
reflection.hasMethod("process") # Truereflection.hasMethod("missing") # FalsesetMethod
Sección titulada «setMethod»Agrega un nuevo método a la clase. Lanza ValueError si el nombre ya existe o 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. Lanza ValueError si el método no existe.
reflection.removeMethod("new_method") # TruegetMethodSignature
Sección titulada «getMethodSignature»Retorna el objeto inspect.Signature de un método específico.
sig = reflection.getMethodSignature("process")# (self) -> strPropiedades
Sección titulada «Propiedades»getProperties
Sección titulada «getProperties»Retorna los nombres de todas las propiedades definidas en la clase.
class Config: @property def host(self) -> str: """Server hostname.""" return "localhost"
@property def _port(self) -> int: return 8080
reflection = ReflectionConcrete(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 ejecutando su getter. Lanza ValueError si no existe o TypeError si no es una propiedad.
value = reflection.getProperty("host") # "localhost"getPropertySignature
Sección titulada «getPropertySignature»Retorna la firma del getter de una propiedad.
sig = reflection.getPropertySignature("host")# (self) -> strgetPropertyDocstring
Sección titulada «getPropertyDocstring»Retorna el docstring del getter de una propiedad, o None si no tiene.
doc = reflection.getPropertyDocstring("host")# "Server hostname."Constructor y Dependencias
Sección titulada «Constructor y Dependencias»getConstructorSignature
Sección titulada «getConstructorSignature»Retorna el objeto inspect.Signature del método __init__.
sig = reflection.getConstructorSignature()# (self, name: str = 'default') -> NoneconstructorSignature
Sección titulada «constructorSignature»Analiza las dependencias del constructor, identificando parámetros resueltos (con valor por defecto o tipo primitivo) y no resueltos (que requieren inyección de dependencias).
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»ReflectionConcrete implementa un sistema de caché en memoria que almacena los resultados de las operaciones de introspección. Esto evita recalcular resultados costosos en llamadas repetidas.
Protocolo de caché
Sección titulada «Protocolo de caché»La instancia soporta acceso tipo diccionario para el caché:
# 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()