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

时间:2013-09-23 09:00:25

标签: python api parameters

我在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方法?

2 个答案:

答案 0 :(得分:1)

我不认为让这两个功能非常糟糕,但可能完全放弃,即没有任何合并。

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

我不太明白为findNodeByLineNo函数提供的变量的含义,但使用findNodeBy您可以使用以下代码实现(或替换)findNode

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

您可能会发现这些便利功能对他们来说很少“肉”,您可以完全放弃它们并在整个代码中使用简单的“findNodeBy”调用。

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

答案 1 :(得分: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