如果不是,则返回错误(python)

时间:2012-04-24 20:42:30

标签: python regex command-line formatting

我有一个针对我的函数的给定输入文件的规则列表。如果在给定的文件中违反了其中任何一个,我希望我的程序返回错误消息并退出。

  • 第一行应以“#”符号开头(表示标题行)
  • 每行应该有10列
  • 第2列(从0开始计算)应为+或 - 符号
  • 第8列应为以逗号分隔的整数列表
  • 第9列应该是以逗号分隔的整数列表,与第8列的整数数字完全相同。

为了尝试这样做,我编写了以下代码:

编辑史蒂夫莎的代码答案

with open(infile, 'r') as fp:
line = fp.readline().strip()
if not line.startswith('#'):
    print ('First line does not start with #')
    sys.exit(1)
n = 1
for line in fp.readlines():
    d = '(\d+,\d+)'
    n += 1
    cols = line.strip().split()
    i = search(d, line)
    if len(cols) != 10:
        print('Lenth not equal to 10')
        sys.exit(1)
    if cols[2] != '+' or '-':
        print('Column 2 is not a + or - symbol')
        sys.exit(1)
    if i and cols[8] != i.group(1):
        print('Column 8 is not a comma-separated list of integers')
        sys.exit(1)
    if i and cols[9] != i.group(1) and len(cols[9]) != len(cols[8]):
        print('Column 9 in not a comma-separated list of integers with the exact same number of integers in column 8')
        sys.exit(1)

然而,当我运行它时,并非所有的条件似乎都有效。我正在尝试正确地做到这一点?

1 个答案:

答案 0 :(得分:3)

这一行错了:

if cols[2] != '+' or '-':

这是正确的:

if not (cols[2] == '+' or cols[2] =='-'):

我建议这样做:

if cols[2] not in ('+', '-'):

另外,我建议你不要致电fp.readlines()。文件对象fp用作迭代器,当您迭代它时,您一次得到一行。所以你的循环将成为:

for line in fp:

此外,看起来n正在跟踪行号?在这种情况下,您可以使用惯用的Python方式,如下所示:

for n, line in enumerate(fp, 1):

enumerate()接受迭代器并从迭代器返回下一个值以及递增计数。默认情况下,计数从0开始,但您可以选择指定起始编号,就像我在此处所做的那样,从1开始。

最好在Python中使用with语句打开文件,所以我建议你这样做:

with open(infile, 'r') as fp:
    line = fp.readline().strip()
    if not line.startswith('#'):
        print ('First line does not start with #')
        sys.exit(1)
    for line in fp:
        # process lines here

您展示的代码对我来说并不完全合理。这一行:

i = search(d, line)

您必须已完成from re import search命令。我实际上建议只做import re,然后明确调用re.search(),但我想这是一个偏好问题。无论如何,这会将i设置为来自re.search()的匹配组结果(如果匹配失败,则设置为None)。但是在代码中稍后您正在测试r而不是i,并且您从未在我们在此处看到的任何代码中设置r,所以我不确定它会做什么。我个人使用m作为匹配组的变量名。

你的正则表达式只匹配一对正整数。没有什么可以计算出有多少整数。 len(cols[8])正在检查cols[8]中的字符数。

您正在调用字符串方法函数.split(''),这是不正确的。在我的系统上,它会引发异常:ValueError: empty separator只需调用.split()即可在空格上分割;我假设逗号分隔的整数列表不能有任何空格。

最后,请考虑PEP 8中的指南。您的变量FirstLine大写为类名而不是变量名;这并没有让我感到困惑,但这有点让人分心。大多数Python社区都遵循PEP 8。

http://www.python.org/dev/peps/pep-0008/

考虑到以上所有因素,我只需重新编写代码:

import sys

def parse_list_of_int(s):
    try:
        return [int(x) for x in s.split(',')]
    except Exception:
        return None

with open("test.txt", 'r') as f:
    # read line 1
    line = f.readline().strip()
    if not line.startswith('#'):
        print ('First line does not start with #')
        sys.exit(1)

    # need to start enumerate() at 2 because we pulled line 1 out above
    for i, line in enumerate(f, 2):
        cols = line.strip().split()
        if len(cols) != 10:
            print('line {0}: Length not equal to 10'.format(i))
            sys.exit(1)
        if cols[2] not in ('+', '-'):
            print('line {0}: Column 2 is not a + or - symbol'.format(i))
            sys.exit(1)
        lst8 = parse_list_of_int(cols[8])
        if lst8 is None:
            print('line {0}: Column 8 is not a comma-separated list of integers').format(i)
            sys.exit(1)
        lst9 = parse_list_of_int(cols[9])
        if lst9 is None:
            print('line {0}: Column 9 is not a comma-separated list of integers'.format(i))
            sys.exit(1)
        if len(lst8) != len(lst9):
            print('line {0}: Column 8 and column 9 do not have same number of integers'.format(i))
            sys.exit(1)

print('No problems!')
sys.exit(0)

我编写了一个简单的函数来解析整数列表,构建一个Python列表并返回它。然后代码可以实际检查两个列表是否长度相同。