首页 > 解决方案 > “类名”对象在递归函数中没有属性“函数名”

问题描述

我正在尝试实现一个递归函数,其中我的基本条件工作正常,另一个条件也工作正常。但是当我跳转到递归条件时,它给了我一个错误,即 "class name" object has no attribute "function name" 。

我的课:

class NGram(object):
    def __init__(self):
        self.n = None
        self.ngramprobability = None
        self.uniquegrams = [
            ["sample", "this"],
            ["is", "a"],
            ["this", "is"],
            ["sample"],
            ["this"],
            ["a"],
            ["is"],
            ["a", "sample"],
        ]

        self.out = [
            [
                ["sample", 0.16666666666666666],
                ["this", 0.3333333333333333],
                ["a", 0.16666666666666666],
                ["is", 0.3333333333333333],
            ],
            [
                ["sample", "this", 1.0],
                ["is", "a", 0.5],
                ["this", "is", 1.0],
                ["a", "sample", 1.0],
            ],
        ]

    def get_prob(self, words):

        if len(words) == 1:
            probability = [j[-1] for i in self.out for j in i if j[:-1] == words][0]
            return probability  # condition works fine

        elif words in self.uniquegrams:
            probability = [j[-1] for i in self.out for j in i if j[:-1] == words][0]
            return probability  # condition works fine
        else:
            return self.get_prob(self, words[1:]) * 0.4

我的脚本引发错误:

# train bi_gram
bi_gram = NGram()

c = bi_gram.get_prob(["this", "sample"])
print(c)

我无法理解我在哪里犯了错误。请帮我解决这个错误。

标签: pythonfunctionrecursion

解决方案


由于您似乎不了解最小可重现示例的含义,因此这里有两个示例(您会注意到我删除了所有不相关的内容,只保留了重现问题所必需的内容):

1/忘记使用self.引用方法:

class NGram(object):
    def get_prob(self, words):
        if len(words) == 1:
            return 1        
        else: 
            return get_prob(words[1:]) * 0.4

ng = NGram()
print(ng.get_prob(["foo"]))
print(ng.get_prob(["foo", "bar"]))

在第二次调用时不断引发 NameError :

1
Traceback (most recent call last):
  File "probs.py", line 10, in <module>
    print(ng.get_prob(["foo", "bar"]))
  File "probs.py", line 6, in get_prob
    return get_prob(words[1:]) * 0.4
NameError: global name 'get_prob' is not defined

2/self.用于引用方法但错误地self作为参数传递:

class NGram(object):
    def get_prob(self, words):
        if len(words) == 1:
            return 1        
        else: 
            return self.get_prob(self, words[1:]) * 0.4

ng = NGram()
print(ng.get_prob(["foo"]))
print(ng.get_prob(["foo", "bar"]))

在第二次调用时不断引发 TypeError :

1
Traceback (most recent call last):
  File "probs.py", line 10, in <module>
    print(ng.get_prob(["foo", "bar"]))
  File "probs.py", line 6, in get_prob
    return self.get_prob(self, words[1:]) * 0.4
TypeError: get_prob() takes 2 positional arguments but 3 were given

为了解决您的问题(如果您完成了本教程,您将不会遇到),正确的方法是:

 class NGram(object):
    def get_prob(self, words):
        if len(words) == 1:
            return 1        
        else: 
            return self.get_prob(words[1:]) * 0.4

ng = NGram()
print(ng.get_prob(["foo"]))
print(ng.get_prob(["foo", "bar"]))

按预期工作:

1
0.4

现在我可以建议您完成完整的官方教程,对于未来的问题,请在此处提问之前进行一些搜索([您应该这样做(https://stackoverflow.com/help/how-to-ask)),并且提供所有相关信息和(在相关时)一个真正的最小且可重复的示例?


推荐阅读