以pythonic方式合并具有两个非重叠参数集的函数

2024-04-27 02:45:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python中解析抽象语法树。为此,我设计了一个自定义树结构和一个操作它的接口。除此之外,我还提供了两种不同的搜索功能:

def findNode(self, start, name)

&

def findNodeByLineno(node, lineno, prevNode, nodeType=None)

第一个函数搜索给定名称的节点,后一个函数比较行号和节点类型(如果给定)。 我的潜意识告诉我,这是一个漏洞百出的界面设计,但我不能想出一个决定如何合并这两个功能在一个共同的功能。你知道吗

def findNode(self, start, name, lineno, prevNode, nodeType) 

在我看来也是错误的,因为它没有明确说明参数集只能分成两组。用户不能仅基于prevNode或仅基于nodeType搜索节点。拥有两个不同的函数似乎是一个非常类似C的解决方案。你知道吗

有没有一个pythonic的方法来解决这个设计冲突?你知道吗


Tags: 函数nameself功能节点def语法start
2条回答

我相信解决这个问题的最好方法是使用一个带有可选参数的简单包装函数。你知道吗

def findNode(start, name):
    pass


def findNodeByLineno(node, lineno, prevNode, nodeType=None):
    pass


def find_node(start=None, name=None, node=None, lineno=None, prevNode=None, nodeType=None):
    if start is not None and name is not None:
            return findNode(start, name)
    else:
        try:
            return findNodeByLineno(node, lineno, prevNode, nodeType)
        except TypeError:
            print("Improper arguments")

控制台会话

>>> from wrapper import find_node
>>> find_node(start="Cheese", name="Cookie")
findNode was called
>>> find_node(node="Cheese", lineno=21, prevNode="Happy", nodeType="Cheese")
findNodeByLineno was called

我不认为拥有这两个功能是非常糟糕的,但它可能只是完全放弃,即没有什么可以合并。你知道吗

其思想是可以将遍历语法树的代码分解成findNodeBy函数。该函数接受一个谓词,并返回第一个节点,给定的谓词为该节点返回True。你知道吗

我不太理解赋予findNodeByLineNo函数的变量的含义,但是使用findNodeBy可以实现(或替换)findNode

def findNode(start, name):
    return findNodeBy(start, lambda n: n.name == name)

您可能会发现,这些方便函数对它们来说“肉”太少了,所以您不妨完全放弃它们,在整个代码中使用普通的“findNodeBy”调用。你知道吗

现在(这一部分对你的问题没有太大影响)你可能会发现,如果你把语法树当作一个iterable,然后用itertools.dropwhile这样的东西来找到一个与谓词匹配的特定元素,你也可以替换findNodeBy。只是一些值得思考的东西。你知道吗

相关问题 更多 >