Inspección
Reflection
Sección titulada «Reflection»La clase Reflection es el punto de entrada central del sistema de introspección de Orionis. Actúa como una fachada estática que unifica el acceso a todas las herramientas de reflexión del framework, proporcionando dos capacidades fundamentales:
- Métodos factoría: crean objetos de reflexión especializados para inspeccionar clases abstractas, concretas, instancias, módulos y callables.
- Métodos de verificación de tipo: permiten determinar la naturaleza de cualquier objeto Python mediante comprobaciones booleanas precisas.
Este diseño centralizado permite al desarrollador y al contenedor de servicios (IoC) analizar cualquier componente del sistema sin necesidad de importar directamente cada clase de reflexión individual.
Importación
Sección titulada «Importación»from orionis.services.introspection.reflection import ReflectionMétodos Factoría
Sección titulada «Métodos Factoría»Los métodos factoría crean instancias de las clases de reflexión especializadas. Cada uno valida el tipo del objeto recibido y lanza TypeError si no es compatible.
instance
Sección titulada «instance»Crea un objeto ReflectionInstance para inspeccionar una instancia de clase.
class UserService: def __init__(self, name: str = "default") -> None: self.name = name
obj = UserService()ri = Reflection.instance(obj)
ri.getClassName() # "UserService"ri.getPublicAttributes() # {"name": "default"}Rechaza instancias de tipos built-in y primitivos:
# TypeError: instancias built-in no son válidasReflection.instance("hello")Reflection.instance(42)Reflection.instance([1, 2, 3])abstract
Sección titulada «abstract»Crea un objeto ReflectionAbstract para inspeccionar una clase abstracta (ABC).
from abc import ABC, abstractmethod
class Repository(ABC): @abstractmethod def find(self, id: int) -> dict: ...
ra = Reflection.abstract(Repository)ra.getClassName() # "Repository"Rechaza clases concretas:
class ConcreteService: pass
# TypeError: no es una clase abstractaReflection.abstract(ConcreteService)concrete
Sección titulada «concrete»Crea un objeto ReflectionConcrete para inspeccionar una clase concreta.
class PaymentService: def process(self) -> bool: return True
rc = Reflection.concrete(PaymentService)rc.getClassName() # "PaymentService"Rechaza clases abstractas:
# TypeError: no es una clase concretaReflection.concrete(Repository)Crea un objeto ReflectionModule para inspeccionar un módulo por su nombre.
rm = Reflection.module("os")rm.getClasses() # clases del módulo osrm.getFunctions() # funciones del módulo osRechaza nombres de módulo inválidos:
# TypeError: módulo inexistenteReflection.module("modulo.inexistente")
# TypeError: cadena vacíaReflection.module("")callable
Sección titulada «callable»Crea un objeto ReflectionCallable para inspeccionar una función o método.
def process_data(items: list, mode: str = "fast") -> str: return f"{len(items)}-{mode}"
rc = Reflection.callable(process_data)Rechaza clases (que aunque son callable, no son funciones):
# TypeError: las clases no son funcionesReflection.callable(PaymentService)Verificación de Tipos
Sección titulada «Verificación de Tipos»La clase Reflection ofrece un conjunto extenso de métodos estáticos booleanos para determinar la naturaleza de cualquier objeto Python. Internamente, la mayoría delegan en el módulo inspect de la librería estándar, mientras que algunos implementan lógica personalizada para cubrir casos específicos del framework.
Tabla de Métodos de Verificación
Sección titulada «Tabla de Métodos de Verificación»| Método | Descripción | Base |
|---|---|---|
isAbstract(obj) | Clase base abstracta con métodos abstractos | inspect.isabstract |
isConcreteClass(obj) | Clase concreta definida por el usuario | Lógica personalizada |
isClass(obj) | Cualquier tipo de clase | inspect.isclass |
isInstance(obj) | Instancia de clase definida por el usuario | Lógica personalizada |
isModule(obj) | Objeto módulo | inspect.ismodule |
isFunction(obj) | Función de Python (incluye async) | inspect.isfunction |
isMethod(obj) | Método enlazado a una instancia | inspect.ismethod |
isRoutine(obj) | Función o método (user-defined o built-in) | inspect.isroutine |
isBuiltIn(obj) | Función o método built-in | inspect.isbuiltin |
isCoroutine(obj) | Objeto coroutine en ejecución | inspect.iscoroutine |
isCoroutineFunction(obj) | Función definida con async def | inspect.iscoroutinefunction |
isAwaitable(obj) | Objeto que puede ser awaited | inspect.isawaitable |
isGenerator(obj) | Objeto generador en ejecución | inspect.isgenerator |
isGeneratorFunction(obj) | Función generadora (yield) | inspect.isgeneratorfunction |
isAsyncGen(obj) | Generador asíncrono en ejecución | inspect.isasyncgen |
isAsyncGenFunction(obj) | Función generadora asíncrona | inspect.isasyncgenfunction |
isGeneric(obj) | Tipo genérico (List[int], TypeVar) | Lógica personalizada |
isProtocol(obj) | Subclase de typing.Protocol | Lógica personalizada |
isTypingConstruct(obj) | Constructo del módulo typing | Lógica personalizada |
isCode(obj) | Objeto code de Python | inspect.iscode |
isDataDescriptor(obj) | Descriptor de datos (ej. property) | inspect.isdatadescriptor |
isFrame(obj) | Objeto frame de ejecución | inspect.isframe |
isTraceback(obj) | Objeto traceback de excepción | inspect.istraceback |
isGetSetDescriptor(obj) | Descriptor getset | inspect.isgetsetdescriptor |
isMemberDescriptor(obj) | Descriptor de miembro | inspect.ismemberdescriptor |
isMethodDescriptor(obj) | Descriptor de método | inspect.ismethoddescriptor |
Verificaciones con Lógica Personalizada
Sección titulada «Verificaciones con Lógica Personalizada»Los siguientes métodos implementan lógica específica del framework que va más allá de lo que ofrece inspect.
isConcreteClass
Sección titulada «isConcreteClass»Determina si un objeto es una clase concreta definida por el usuario. Excluye: tipos built-in, clases abstractas, genéricos, protocolos, constructos de typing y clases que heredan directamente de ABC.
class MyService: pass
Reflection.isConcreteClass(MyService) # TrueReflection.isConcreteClass(int) # True (no es builtin function)Reflection.isConcreteClass(Repository) # False (abstracta)Reflection.isConcreteClass(list[int]) # False (genérico)Reflection.isConcreteClass("hello") # False (no es una clase)isInstance
Sección titulada «isInstance»Determina si un objeto es una instancia de una clase definida por el usuario. Excluye instancias de módulos builtins y abc.
obj = MyService()Reflection.isInstance(obj) # TrueReflection.isInstance("hello") # False (builtin)Reflection.isInstance(42) # False (builtin)Reflection.isInstance(MyService) # False (es una clase, no instancia)isGeneric
Sección titulada «isGeneric»Detecta tipos genéricos del sistema de typing, incluyendo alias genéricos (List[int]), tipos con __origin__, _GenericAlias y TypeVar.
from typing import TypeVar
T = TypeVar("T")
Reflection.isGeneric(list[int]) # TrueReflection.isGeneric(dict[str, int]) # TrueReflection.isGeneric(T) # TrueReflection.isGeneric(MyService) # FalseisProtocol
Sección titulada «isProtocol»Verifica si un objeto es una subclase de typing.Protocol (pero no Protocol en sí mismo).
from typing import Protocol
class Greeter(Protocol): def greet(self) -> str: ...
Reflection.isProtocol(Greeter) # TrueReflection.isProtocol(Protocol) # False (es Protocol mismo)Reflection.isProtocol(MyService) # FalseisTypingConstruct
Sección titulada «isTypingConstruct»Identifica constructos del módulo typing comparando el nombre del tipo del objeto con una lista conocida que incluye: Any, Union, Optional, List, Dict, Set, Tuple, Callable, TypeVar, Generic, Protocol, Literal, Final, TypedDict, NewType, Deque, DefaultDict, Counter y ChainMap.
from typing import TypeVar
T = TypeVar("T")
Reflection.isTypingConstruct(T) # TrueReflection.isTypingConstruct(MyService) # FalseReflection.isTypingConstruct(42) # FalseEjemplo de Uso Integrado
Sección titulada «Ejemplo de Uso Integrado»from orionis.services.introspection.reflection import Reflection
class Logger: def log(self, message: str) -> None: print(message)
# Verificar el tipo antes de crear el objeto de reflexiónif Reflection.isConcreteClass(Logger): rc = Reflection.concrete(Logger) print(rc.getClassName()) # "Logger" print(rc.getPublicMethods()) # ["log"]
# Inspeccionar una instancialogger = Logger()if Reflection.isInstance(logger): ri = Reflection.instance(logger) print(ri.getClass()) # <class 'Logger'> print(ri.hasMethod("log")) # True
# Verificar naturaleza de funcionesasync def fetch_data() -> dict: return {}
Reflection.isCoroutineFunction(fetch_data) # TrueReflection.isFunction(fetch_data) # TrueReflection.isBuiltIn(fetch_data) # False