pylint如何记住之前运行的分数?

18

在典型的pylint运行中,我们会得到以下输出:

Global evaluation
-----------------
Your code has been rated at 9.50/10 (previous run: 8.50/10)

Duplication
-----------

+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |0        |=          |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |0.000    |=          |
+-------------------------+------+---------+-----------+

我想知道pylint如何记住之前运行的分数 - 在上面的例子中,之前运行时的得分为8.5。

我想在自己的模块中实现类似的功能,所以我首先想找出pylint是如何实现这个功能的。

我搜索了可能存储这些数据的隐藏文件夹,但没有找到任何文件夹。


你可以将文件作为字典的键并使用pickle进行存储,如果该键已存在,则说明你之前已经使用过该文件,然后检查其先前的值。 - Padraic Cunningham
谢谢,但您确定这就是pylint的实现方式吗?我找不到任何与我的源代码相关的pickled文件。 - Kaushik Pavani
1
另外,我尝试从不同的目录运行相同的.py文件来运行pylint,但是pylint似乎记住了之前的分数。这似乎表明pylint没有在本地存储先前的分数。它似乎可以全局访问上一次运行的分数。 - Kaushik Pavani
2个回答

15

我在我的主目录下有一个.pylintrc文件,其中包含以下行:

#pickle collected data for later comparisons.
persistent=yes

看起来 pylint 确实在比较时使用了 pickle。

从源代码中的 lint.py 文件可以看出:

def make_options():
        return (('ignore',
                 {'type' : 'csv', 'metavar' : '<file>[,<file>...]',
                  'dest' : 'black_list', 'default' : ('CVS',),
                  'help' : 'Add files or directories to the blacklist. '
                           'They should be base names, not paths.'}),
                ('persistent',
                 {'default': True, 'type' : 'yn', 'metavar' : '<y_or_n>',
                  'level': 1,
                  'help' : 'Pickle collected data for later comparisons.'})

完整的lint.py源代码在这里

最有趣的部分可能是这个方法:

def close(self):
        """close the whole package /module, it's time to make reports !

        if persistent run, pickle results for later comparison
        """
        if self.file_state.base_name is not None:
            # load previous results if any
            previous_stats = config.load_results(self.file_state.base_name)
            # XXX code below needs refactoring to be more reporter agnostic
            self.reporter.on_close(self.stats, previous_stats)
            if self.config.reports:
                sect = self.make_reports(self.stats, previous_stats)
                if self.config.files_output:
                    filename = 'pylint_global.' + self.reporter.extension
                    self.reporter.set_output(open(filename, 'w'))
            else:
                sect = Section()
            if self.config.reports or self.config.output_format == 'html':
                self.reporter.display_results(sect)
            # save results if persistent run
            if self.config.persistent:
                config.save_results(self.stats, self.file_state.base_name)
        else:
            self.reporter.on_close(self.stats, {})

您还需要查看config.py源代码

def load_results(base):
    """try to unpickle and return data from file if it exists and is not
    corrupted

    return an empty dictionary if it doesn't exists
    """
    data_file = get_pdata_path(base, 1)
    try:
        with open(data_file, _PICK_LOAD) as stream:
            return pickle.load(stream)
    except:
        return {}

3
非常好,谢谢。我发现我的主目录中有一个名为“.pylint.d”的文件夹,看起来包含了我正在寻找的数据。 - Kaushik Pavani
没问题。我不确定是否应该这样做,但我认为这是实现你想要的功能的简单方法。 - Padraic Cunningham
如果按照现有的代码运行load_results函数中的try语句块,它将总是执行except语句并返回一个空字典,因为_PICK_LOAD未定义。必须查看代码才能发现在 Python2 中__PICK_LOAD是'r',而在Python3中是'rb'。我建议将except:更改为except IOError:。这适用于Python2和Python3。 - Tom Ekberg

0
根据这里所述:
分析数据以pickle文件的形式存储在一个目录中,该目录根据以下规则进行本地化:
- 如果设置了PYLINTHOME环境变量,则使用该变量的值。 - 如果设置了用户的XDG_CACHE_HOME环境变量,则使用用户的XDG_CACHE_HOME目录下的"pylint"子目录。 - Linux:使用"~/.cache/pylint"目录。 - macOS:使用"~/Library/Caches/pylint"目录。 - Windows:使用"C:UsersAppDataLocalpylint"目录。 - 在当前目录中的".pylint.d"目录。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接