类方法没有找到给定的参数

时间:2018-06-15 00:56:08

标签: python

我刚刚学会了如何在C#中创建二进制搜索树。我决定尝试在Python 3.x中编写相同的代码。但是,当我使用我的Print方法时,出现了这个错误:

Traceback (most recent call last):
  File "C:\Users\danie\Desktop\Python\BinarySearchTree\BinarySearchTree\BinarySearchTree.py", line 62, in <module>
    b.BSTprint()
  File "C:\Users\danie\Desktop\Python\BinarySearchTree\BinarySearchTree\BinarySearchTree.py", line 46, in BSTprint
    BST.Print(current)
TypeError: Print() missing 1 required positional argument: 'cur'

问题是,我确实提出了所需的位置参数。我尝试自己修复它,发现如果我删除了 self 参数,它就可以了。但是,我一直认为你需要在所有类方法中都有 self 参数。我不知道出了什么问题。这是代码

import random
class BST:
    #Node class 
    class Node:
        data = None
        left = None
        right = None
        def __init__(self, d):
            self.data = d
    first = None
    #Add method
    def Add(self, d):
        #Checks if the Binary Search Tree is empty
       if(BST.first == None):
           BST.first = BST.Node(d)
           #Debugging purposes
           #print("Added: {}".format(d))
           return;
       else:
           newNode = BST.Node(d)
           cur = BST.first
           while(cur != None):
               if(cur.data < newNode.data):
                   if(cur.left == None):
                       cur.left = newNode
                       #print("Added: {}".format(newNode.data))
                       return
                   else:
                       cur = cur.left
               elif(cur.data > newNode.data):
                   if(cur.right == None):
                       cur.right = newNode
                       #print("Added: {}".format(newNode.data))
                       return
                   else:
                       cur = cur.right
               else:
                    print("Value already in BST")
                    return


    def BSTprint(self):
        current = BST.first
        if(current == None):
            return
        BST.Print(current)
    def Print(self, cur):

        if(cur.left != None):
            BST.Print(cur.left)
        print(cur.data)
        if(cur.right != None):
            BST.Print(cur.right)



b = BST()
#Adds values into BST
for i in range(10):
    x = random.randint(1,100)
    b.Add(x)
b.BSTprint()

3 个答案:

答案 0 :(得分:1)

你已经混淆了类变量和实例变量。

在Python中,方法的第一个参数是为调用对象保留的(除非在某些情况下它们不是,例如在classmethods或staticmethods中)。像这样修改Add方法:

class BST:
...
    def Add(self, d):
        if self.first is None:
            self.first = BST.Node(d)
            return
    ...

请注意BST.Node(d)仍然是相同的,因为我指的是属于该类的东西:另一个类。

BST.Print(current)修改为self.Print(current)

将BST的根节点称为first,而不是更喜欢root,这种情况并不常见!

答案 1 :(得分:1)

我想强调的事情:

BST是一个类

Print是一个对象方法(绑定到对象而不是类),它需要传递对象引用(self),这与其他语言Java / C ++不同。

你正在调用BST.Print,这类似于在Java / C ++中调用静态方法,但它错了,因为Print方法采用了对象参数

由于您正在调用一个对象绑定的方法(因为它需要self参数),您需要使用对象调用它。

重点是:

如果您使用带有self参数的方法,那么应该使用对象调用它们。如果要从类中调用它们,则可以使用@staticmethod并删除self参数并传递要处理的对象

请参阅: Difference between Class and Instance methods

希望这有帮助

答案 2 :(得分:0)

正如其他人所说,在self.BSTprint(node)方法中,您需要将first = None作为实例方法调用,例如first,以便将实例正确传递给方法。但是您的代码还存在一些其他问题。

执行BST创建BST作为类属性,这意味着它将由所有first个实例共享。这不是一个好主意:每个实例都应该有自己的根节点!当然,如果程序只创建一个__init__实例,您就不会注意到该错误,但如果您决定要创建多个树,则会发生错误的事情。 ;)

相反,您应该创建Node作为实例属性,通常的方法是使用Node方法。

您的代码定义了BST类中的Add类。这样做很好,但在Python中有点不寻常。将它作为一个单独的类更简单。再一次,您将is属性定义为类属性。这实际上是可以的,因为你从不修改那些类属性:你的None方法创建具有“阴影”类属性的相同名称的实例属性。但是,如果你摆脱了那些类属性并且只是从一开始就使用实例属性,它会使代码分析更简单。

以下是您的代码的修改版本。我做了一些修饰,以便代码符合Python PEP-0008样式指南。简单的变量,属性和方法名称应以小写字母开头。我也摆脱了多余的括号。并且建议在测试==单例时使用!=,与使用firstroot值测试相比,它更有效(并且更好阅读)。

根据BerkÖzbalcı的评论,我将Node更改为__repr__。我给了random.seed一个import random random.seed(42) class Node: """ A binary tree node """ def __init__(self, d): self.data = d self.left = self.right = None def __repr__(self): return repr(self.data) class BST: """ Binary search tree """ def __init__(self): self.root = None def add(self, d): # Check if the Binary Search Tree is empty if self.root is None: self.root = Node(d) #Debugging purposes print("Added: {} root".format(self.root)) return else: newNode = Node(d) cur = self.root while cur is not None: if cur.data < newNode.data: if cur.left is None: cur.left = newNode print("Added: {} left".format(newNode)) return else: cur = cur.left elif cur.data > newNode.data: if cur.right is None: cur.right = newNode print("Added: {} right".format(newNode)) return else: cur = cur.right else: print("Value already in BST:", d) return def bst_print(self): current = self.root if current is None: return self.show(current) def show(self, cur=None): if cur.left is not None: self.show(cur.left) print(cur) if cur.right is not None: self.show(cur.right) b = BST() # Add values into BST for i in range(10): x = random.randint(1, 100) print(x) b.add(x) print('\nSorted') b.bst_print() 方法,以便更轻松地打印节点数据。

我还添加了对82 Added: 82 root 15 Added: 15 right 4 Added: 4 right 95 Added: 95 left 36 Added: 36 left 32 Added: 32 right 29 Added: 29 right 18 Added: 18 right 95 Value already in BST: 95 14 Added: 14 left Sorted 95 82 36 32 29 18 15 14 4 的调用,其中包含硬编码的种子值,以便程序在每次运行时生成相同的数字。这使得测试和调试变得更加容易。当数据不断变化时,很难弄清楚出了什么问题。

{{1}}

<强>输出

{{1}}