【问题标题】:Invalid numbers of args (TypeError), though exact args givenargs 的数量无效(TypeError),尽管给出了确切的 args
【发布时间】:2015-11-11 13:34:06
【问题描述】:

我正在尝试创建一个二叉搜索树,但它给了我一个TypeError。如何将第二个参数 (node) 作为对象本身传递给 insert(),因为第一个参数 (self) 始终是 BSTNode 的实例。

# Binary Search Tree
# Create a BST and insert elements and print Inorder traversal


class BSTNode(object):
    def __init__(self, key, left=None, right=None):
        self.left = left
        self.right = right
        self.key = key

    @property
    def insert(self, node, key):
        if node is None:
            return BSTNode(key)
        elif key < node.key:
            node.left = insert(node.left, key)
        elif key > node.key:
            node.right = insert(node.right, key)
        return node

    @property
    def inorder(root):
        if root:
            inorder(root.left)
            print(root.key)
            inorder(root.right)

if __name__ == "__main__":
    bst = BSTNode(50)
    bst.insert(bst, 30)
    bst.insert(bst, 20)
    bst.insert(bst, 40)
    bst.insert(bst, 70)
    bst.insert(bst, 60)
    bst.insert(bst, 80)

    inorder(root)

无论我向insert() 传递多少个参数,上面的代码都会给出相同的错误:

Traceback (most recent call last):
  File "bst.py", line 31, in <module>
    bst.insert(root, 30)
TypeError: insert() takes exactly 3 arguments (1 given)

【问题讨论】:

  • 您认为@property 到底是什么?你根本没有正确使用它。
  • 只需删除 @property 装饰器。属性是一个声明为 getter 的函数,它接受一个参数:self 并返回属性的值。优点是能够调用val = obj.prop 而不是val = obj.prop(),从而掩盖了属性是计算而不是固定值的事实。
  • 在不正确的 @property 用法之上,python 中的方法调用需要 self 前缀。使用self.insert()self.inorder()
  • 最后一行 inorder(root) 更改 bst.inorder(root) 或创建函数 inorder() 不在类中,并定义 root

标签: python oop binary-search-tree


【解决方案1】:

您不应该在这里为insert() 函数创建@property(在这种情况下也不应该为inorder())。

应该使用属性来管理具有 getter setter 和 deleter 的类的属性。 getter(您使用@property 装饰创建并在通过bst.insert 访问属性时调用)必须采用单个 参数self。然后,它(通常)返回分配给它的属性。

相反,像普通的method 一样使用它并添加元素而不装饰它,注意我是如何将self 添加到您的insert() 调用中的:

 def insert(self, node, key):
    if node is None:
        return BSTNode(key)
    elif key < node.key:
        node.left = self.insert(node.left, key)
    elif key > node.key:
        node.right = self.insert(node.right, key)
    return node

现在您的插入工作正常并返回新的节点对象:

bst.insert(root, 30)
# returns <__main__.BSTNode at 0x7fd9f74a8668>

发生这种情况的原因是,属性的​​ (__get__) 函数在内部调用了您装饰为 getter 的函数 (insert),但只有一个参数 insert(instanceOfClass)

因为你已经用多个参数定义了你的函数insert(),所以当这个调用被调用时你会得到一个漂亮的小TypeError

【讨论】:

    【解决方案2】:

    @rohit varshney

    原因:属性装饰器有 3input args(fget,fset,fdel), doc string。

    这里的属性装饰器使用不当,因此出现错误。

    修复:请删除插入定义上方的@property。

    装饰器教程: https://dzone.com/articles/python-201-decorators

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-25
      • 1970-01-01
      • 1970-01-01
      • 2017-10-27
      • 1970-01-01
      相关资源
      最近更新 更多