You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用闭包实现Data类链式where过滤API的替代方案

方案1:结构化操作栈实现(完全无闭包)

这个思路的核心是把Expr的每一步操作换成操作类型+参数的结构化数据存储,而不是存lambda闭包,执行逻辑统一放在求值方法里实现,完全避免匿名函数的使用:

from __future__ import annotations
from typing import Dict, Any, Tuple, List
import numpy as np

class Data:
    def __init__(self, data: Dict):
        self._data = data
        
    def where(self, e: Expr) -> Data:
        idx = e.eval(self)
        for k,v in self._data.items():
            self._data[k] = v[idx]
        return self
    
    def __repr__(self):
        return str(self._data)

class Expr:
    def __init__(self):
        # 操作栈存储(操作类型, 参数),完全不存储闭包/匿名函数
        self._ops: List[Tuple[str, Any]] = []
        
    def col(self, s: str) -> Expr:
        self._ops.append(("get_column", s))
        return self

    def equals(self, el: Any) -> Expr:
        self._ops.append(("equal_compare", el))
        return self
        
    def eval(self, data_inst: Data) -> np.ndarray:
        current_val = None
        for op_type, op_param in self._ops:
            if op_type == "get_column":
                current_val = data_inst._data[op_param]
            elif op_type == "equal_compare":
                current_val = current_val == op_param
            # 后续要扩展大于、小于、四则运算等操作,只需要新增分支即可
        return current_val
    
def col(s: str) -> Expr:
    return Expr().col(s)

这个方案没有任何闭包相关的逻辑,所有执行规则都是显式定义的,更容易调试和序列化,非常适合轻量过滤场景。


方案2:表达式树实现(可扩展复杂语法)

如果你需要支持更自然的调用语法(比如直接写col("a") == 3代替.equals(3)),可以用多态表达式节点的方案,也是Spark、Polars等大数据框架内部DSL的标准实现思路,同样不需要闭包:

from __future__ import annotations
from typing import Dict
import numpy as np

class Data:
    def __init__(self, data: Dict):
        self._data = data
        
    def where(self, e: ExprNode) -> Data:
        idx = e.eval(self)
        for k,v in self._data.items():
            self._data[k] = v[idx]
        return self
    
    def __repr__(self):
        return str(self._data)

# 表达式节点基类
class ExprNode:
    def eval(self, data: Data):
        raise NotImplementedError

# 取列节点
class ColNode(ExprNode):
    def __init__(self, col_name: str):
        self.col_name = col_name
    def eval(self, data: Data):
        return data._data[self.col_name]
    # 重载运算符实现更自然的语法
    def __eq__(self, other) -> ExprNode:
        return EqualNode(self, other)
    def __gt__(self, other) -> ExprNode:
        return GreaterNode(self, other)

# 相等比较节点
class EqualNode(ExprNode):
    def __init__(self, left: ExprNode, right: Any):
        self.left = left
        self.right = right
    def eval(self, data: Data):
        return self.left.eval(data) == self.right

# 大于比较节点
class GreaterNode(ExprNode):
    def __init__(self, left: ExprNode, right: Any):
        self.left = left
        self.right = right
    def eval(self, data: Data):
        return self.left.eval(data) > self.right

def col(s: str) -> ColNode:
    return ColNode(s)

# 调用时可以直接写成更符合直觉的语法
# data = Data(inpt).where(col("a") == 3)

这个方案支持任意复杂的表达式嵌套组合,扩展性极强,适合需要构建复杂查询逻辑的场景。

内容的提问来源于stack exchange,提问作者FredMaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 09:03:04