如何获取熊猫发出的警告的行号

时间:2019-07-16 13:09:36

标签: python python-3.x pandas warnings

已编辑:

我有一些用Python编写的代码,并使用熊猫制作和操纵了一些DataFrame。在其中一些中,我得到了一些警告。例如settingwithcopywarning或performancewarning。我想抓住 lineno 发生警告的信息,为此,我编写了以下代码。我抓住了除lineno外的所有东西。

scripts = ['myfile.py', 'myotherfile.py']
with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("default")
    for s in scripts:
        with open(s) as f:
            try:
                exec(f.read())
            except Exception as e:
                print('An Error happend during the execution', e)
                raise
            finally:    
                f.close()    

    print(color.orange('There are {} error/s happend in {}.'.format(len(w), s)))
    for i in range(0, len(w)):
        print(color.green('LineNo: '), w[i].lineno)
        print(color.green('Line: '), w[i].line)
        print(color.green('warning category: '), w[i].category.__name__)
        print(color.green('Warning: '), w[i].message) 
        print(color.green('filename: '), w[i].file) 
        print(color.cyan('-' * 40))

对于w[i].lineno,我希望行号

我得到的号码不属于原始文件。它属于python核心模块。我得到类似5312的信息。 如何将lineno追溯到我自己的脚本?

1 个答案:

答案 0 :(得分:1)

缺少msg.line时,warnings module uses linecache会查找源代码行。

if msg.line is None:
    try:
        import linecache
        line = linecache.getline(msg.filename, msg.lineno)
        ...

您可以做同样的事情:

import warnings
import linecache
import numpy as np
import pandas as pd

with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("default")

    # trigger a SettingWithCopyWarning
    df = pd.DataFrame(np.random.randint(10, size=(10,3)), columns=list('ABC'))
    subdf = df.iloc[::2]
    subdf.loc[:, 'A'] = 99

    for wi in w:
        if wi.line is None:
            wi.line = linecache.getline(wi.filename, wi.lineno)
        print('line number {}:'.format(wi.lineno)) 
        print('line: {}'.format(wi.line))

打印

line number 633:
line:                     self.obj[item_labels[indexer[info_axis]]] = value