0

我在 Python 中解析抽象语法树。为此,我设计了一个自定义树结构和一个对其进行操作的界面。其中,我提供了 2 种不同的搜索功能:

def findNode(self, start, name)

&

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

第一个函数搜索给定名称的节点,后一个函数比较行号和节点的类型(如果给定)。我的潜意识告诉我,这是一个泄漏的界面设计,但我无法决定如何将这两个功能合并到一个通用功能中。

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

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

有没有解决这种设计冲突的pythonic方法?

4

2 回答 2

1

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

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

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

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

您可能会发现这些便利函数对它们的“内容”太少了,您可以完全放弃它们并在整个代码中使用简单的“findNodeBy”调用。

现在(这部分不太影响您的问题)然后您可能会发现findNodeBy如果您将语法树视为可迭代的,然后使用诸如itertools.dropwhile查找与谓词匹配的特定元素之类的东西,您也可以替换。只是一些思考的食物。

于 2013-09-23T10:06:59.273 回答
0

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

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
于 2013-09-23T09:51:15.677 回答