Sfoglia il codice sorgente

增加任意对象的动态解析方法

dongzhaorui 3 mesi fa
parent
commit
c8d86e12a6
1 ha cambiato i file con 55 aggiunte e 0 eliminazioni
  1. 55 0
      FworkSpider/feapder/utils/tools.py

+ 55 - 0
FworkSpider/feapder/utils/tools.py

@@ -16,6 +16,7 @@ import functools
 import hashlib
 import html
 import importlib
+import inspect
 import json
 import os
 import pickle
@@ -1938,6 +1939,60 @@ def get_method(obj, name):
         return None
 
 
+def resolve_method(context, target):
+    """
+    解析目标字符串并返回可调用的方法。
+
+    :param context: 上下文,可以是单个对象或上下文字典。
+                   - 如果是类、函数或模块,直接使用该对象。
+                   - 如果是类实例,直接使用该对象解析方法。
+                   - 如果是字典,则按键值解析对象。例如 {'self': instance, 'other': other_instance}
+    :param target: 目标字符串,例如 'self.detail_get' 或 'other.some_method'
+    :return: 可调用的方法对象
+    """
+    target = str(target)
+    if "." not in target or target.count(".") != 1:
+        raise ValueError(
+            f"Invalid target format: {target}. "
+            f"Expected format: 'object.method'."
+        )
+
+    obj_name, method_name = target.split(".", 1)
+
+    # 解析上下文
+    if isinstance(context, dict):
+        # 如果是字典,按对象名获取对象
+        obj = context.get(obj_name)
+        if obj is None:
+            raise ValueError(f"Object '{obj_name}' not found in context.")
+    elif inspect.isclass(context) or inspect.isroutine(context) or inspect.ismodule(context):
+        # 如果是类、函数或模块,直接使用该对象
+        obj = context
+        if obj_name != getattr(obj, "__name__", None) and obj_name != "self":
+            raise ValueError(
+                f"Unsupported object name: {obj_name}. "
+                f"Expected '{getattr(obj, '__name__', None)}' or 'self'."
+            )
+    elif isinstance(context, object):
+        # 如果是类实例,直接使用该对象
+        obj = context
+        if obj_name != getattr(obj.__class__, "__name__", None) and obj_name != "self":
+            raise ValueError(
+                f"Unsupported object name: {obj_name}. "
+                f"Expected '{getattr(obj.__class__, '__name__', None)}' or 'self'."
+            )
+    else:
+        raise TypeError("Context must be either class, function, module or instance.")
+
+    method = getattr(obj, method_name, None)
+    if method is None or not callable(method):
+        raise AttributeError(
+            f"Method '{method_name}' not found or not callable on object '{obj_name}'."
+        )
+
+    return method
+
+
 def witch_workspace(project_path):
     """
     @summary: