Name error: 'self' not defined - when calling a function to create in-class variables

Name error: 'self' not defined - when calling a function to create in-class variables

我有以下 class:

class Documents:
    def __init__(self, input_file):
        self.input_file_ = input_file #List in which each element is a list of tokens
        
        assert type(self.input_file_) is list, 'Input file is not a list'
        assert type(self.input_file_[0]) is list, 'Elements in input file are not lists' #Only checks first instance, not all. But should suffice
                
    def get_vocabulary(self):
        vocabulary = set([el for lis in self.input_file_ for el in lis])
        return vocabulary, len(vocabulary) 
    
    vocabulary, vocabulary_size = self.get_vocabulary()

但是当我尝试执行它时,出现以下错误:

Traceback (most recent call last):

  File "<ipython-input-34-4268f473c299>", line 1, in <module>
    class Documents:

  File "<ipython-input-34-4268f473c299>", line 30, in Documents
    vocabulary, vocabulary_size = self.get_vocabulary()

NameError: name 'self' is not defined

这是 SO 上的常见错误。但是,我还没有找到代码具有类似结构的答案。

有人可以向我解释为什么会出现此错误以及如何更改我的代码以免出现错误吗?

按照你的方式,vocabulary, vocabulary_size = self.get_vocabulary() 正在执行 当 class 被定义时 ,所以没有 self。后者是传递给 class 方法的第一个参数的名称,并且是要对其进行操作的 class(之前创建的)的实例。

执行此操作的正确方法是在 class 的实例存在并正在初始化时从 __init__() 方法调用 get_vocabulary() 方法。

我的意思是:

class Documents:
    def __init__(self, input_file):
        self.input_file_ = input_file # List in which each element is a list of tokens
        self.vocabulary, self.vocabulary_size = self.get_vocabulary()

        assert type(self.input_file_) is list, 'Input file is not a list'
        assert type(self.input_file_[0]) is list, 'Elements in input file are not lists' # Only checks first instance, not all. But should suffice

    def get_vocabulary(self):
        vocabulary = set([el for lis in self.input_file_ for el in lis])
        return vocabulary, len(vocabulary)

评论(题外话):

在具有 classes 并支持面向对象代码(如 Python)的语言中,通常最好尽可能避免类型检查,因为它不支持 subtyping — but you can overcome that limitation when it is done by using the built-in isinstance() 内置函数。

这意味着在您的 __init__() 方法中执行以下操作可能会更好:

    assert isinstance(self.input_file, list), 'Input file is not a list'
    assert isinstance(self.input_file_[0], list), 'Elements in input file are not lists' # Only checks first instance, not all. But should suffice