拥有以调用另一个函数为唯一目的的函数是个好主意吗?

Is it a good idea to have functions whose sole purpose it is to call another function?

我为树遍历编写了代码。在Binary_treeclass中,我写了三个方法:__Inorder__Postorder__Preorder,用于树的遍历;并且我写了另外三个方法来调用它们并将self.root作为参数传递,这样我就不必每次要遍历时都手动传递它。

代码:

class Node():

    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

class Binary_Tree():

    def __init__(self):
        self.root = None
    
    def insert(self, data):
        new_node = Node(data)
        if self.root == None:
            self.root = new_node
        else:
            current_node = self.root
            while True:
                if data > current_node.data:
                    if not current_node.right:
                        current_node.right = new_node
                        return
                    else:
                        current_node = current_node.right
                else:
                    if not current_node.left:
                        current_node.left = new_node
                        return
                    else:
                        current_node = current_node.left
    
    def inorder_traversal(self):
        return self.__Inorder(self.root)
    
    def postorder_traversal(self):
        return self.__Postorder(self.root)
    
    def preorder_traversal(self):
        return self.__Preorder(self.root)
    
    def __Inorder(self, current_node, visited_node = None):
        if visited_node is None:
            visited_node = []
    
        if current_node:
            self.__Inorder(current_node.left, visited_node)
            visited_node.append(current_node.data)
            self.__Inorder(current_node.right, visited_node)
    
        return visited_node 
        
    def __Postorder(self, current_node, visited_node = None):
        if visited_node is None:
            visited_node = []
    
        if current_node:
            self.__Postorder(current_node.left, visited_node)
            self.__Postorder(current_node.right, visited_node)
            visited_node.append(current_node.data)
    
        return visited_node
    
    def __Preorder(self, current_node, visited_node = None):
        if visited_node is None:
            visited_node = []
    
        if current_node:
            visited_node.append(current_node.data)
            self.__Preorder(current_node.left, visited_node)
            self.__Preorder(current_node.right, visited_node)
        
        return visited_node

我向一个认识的人展示了这段代码,他说“编写一个其唯一指令就是调用另一个函数的函数是没有意义的”,这是糟糕的代码编写。那么,这是真的吗?如果是,那我应该怎么做?

你的朋友错了。

您的函数(如 inorder_traversal)不仅仅是调用另一个函数:它还不允许调用者传递任何参数,这些参数是 none 他们的业务(current_nodevisited_node).这使得拥有一个干净的 public 方法成为一个很好的决定,而带下划线的“私有”函数处理反映在其函数参数中的实现细节。

这不是您的问题,但我确实看到了一些避免代码重复的空间,因为您的基本函数具有非常相似的代码。您也可以考虑为它们创建生成器而不是填充列表。您还可以考虑将这些私有方法移动到 Node class.

例如:

class Node():

    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

    def traverse(self, order=0):
        if order == -1:
            yield self.data
        if self.left:
            yield from self.left.traverse(order)
        if order == 0:
            yield self.data
        if self.right:
            yield from self.right.traverse(order)
        if order == 1:
            yield self.data
        

class Binary_Tree():

    def __init__(self):
        self.root = None
    
    def insert(self, data):
        new_node = Node(data)
        if self.root == None:
            self.root = new_node
        else:
            current_node = self.root
            while True:
                if data > current_node.data:
                    if not current_node.right:
                        current_node.right = new_node
                        return
                    else:
                        current_node = current_node.right
                else:
                    if not current_node.left:
                        current_node.left = new_node
                        return
                    else:
                        current_node = current_node.left
    
    def preorder_traversal(self):
        if self.root:
            return self.root.traverse(-1)

    def inorder_traversal(self):
        if self.root:
            return self.root.traverse(0)
    
    def postorder_traversal(self):
        if self.root:
            return self.root.traverse(1)
    
# Demo run
tree = Binary_Tree()
for data in (4,2,3,1,6,5,7):
    tree.insert(data)
print(*tree.inorder_traversal())