在1000多行文本文件中使用argparse过滤以特定单词开头的行
首先,如果我看起来很无知,我提前表示抱歉。在一周前,我对编程一无所知,但现在我意识到这是一项非常有价值的技能,所以我想学习一些我们科学实验室程序员做的事情。好了,背景介绍到此为止。
他开发的一个非常有用的程序是处理一个pdb文件(其实就是一个很大的文本文件,超过1000行),并根据他想查看的内容,只筛选出以特定单词开头的行。每一行的格式和长度都是一样的,这样应该会更简单。筛选出这些单词后,他会提取与这些行相关的数据,并用这些数据进行计算。举个例子,一行可能是这样的:
ATOM 1 N MET A 1 36.886 53.177 ... (more data)
所以我的问题是:他建议我看看argparse来帮助筛选,但我实在搞不懂argparse的帮助文档或教程。请问这可能吗?如果可以的话,能否请你们这些好心人帮我指个方向?谢谢!
3 个回答
来自argparse
的文档:
argparse
模块让你可以轻松地编写用户友好的命令行界面。程序会定义它需要哪些参数,然后argparse
会帮你从系统参数中提取这些参数。
在Python中,还有更好的方法来解析文件。例如,你可以:
with open('file', 'r') as f:
for line in f:
if line.startswith('ATOM'):
print line
如果你想检查多个关键词,可以考虑使用re
模块,它可以检查正则表达式:
import re
keywords = ['ATOM', 'TOM', 'OM']
pattern = re.compile('^(?:' + '|'.join(keywords) + ').*$', re.MULTILINE)
with open('DATA', 'r') as f:
for line in pattern.findall(f.read()):
print line
我觉得这里有点混淆。
Argparse是Python自带的一个库,它可以让你轻松处理命令行参数——简单来说,就是帮你创建一个别人可以用来运行你程序的界面。
过滤文本文件的任务和argparse的功能是完全不同的。如果你觉得这样更好理解,可以把argparse看作是在运行程序之前获取信息和配置选项的工具。至于实际的过滤操作,你需要自己来编写代码。
不知道什么是命令行?这里有一个不错的入门介绍。还有一个关于如何使用命令行的教程。
注意:这个回答并不是在讨论如何扫描PDB文件以查找关键词,而是主要说明argparse包能做什么。
当你的朋友说argparse可以“帮助过滤PDB文件”时,其实是指它能帮助你创建一个更友好的程序来过滤PDB文件。
如果没有argparse
,人们可能会写出这样的代码:
import sys
keyword = sys.argv[2]
pdb_file = sys.argv[1]
# and then go on using it, say you already have a PDB file scanning function
search_pdb_with_keyword(pdb_file, keyword)
如果用户在使用你的Python脚本时没有指定任何参数,他或她会看到:
$ python pdb_search.py
Traceback (most recent call last):
File "pdb_search.py", line 3, in <module>
keyword = sys.argv[2]
IndexError: list index out of range
这个错误可能会让人困惑,对用户来说一点帮助都没有,除非他对Python有一点了解。即使出现了这个错误,用户也不知道:
- 你的程序需要多少个参数
- 这些参数的位置是什么
- 接受什么类型的参数。
你可以(稍微)改善上面这种不好的做法,写一些简单的验证:
from __future__ import print_function
import sys
import os
if len(sys.argv) == 3:
pdb_file = sys.argv[1]
keyword = sys.argv[2]
if keyword not in ("ATOM", "HETATM"):
print("Invalid keyword!", file=sys.stderr)
sys.exit(1) # abort
if not os.path.exists(pdb_file):
print("File {} does not exist.".format(pdb_file), file=sys.stderr)
sys.exit(1)
else:
print("Usage: {} <pdb_file> <ATOM|HETATM>", file=sys.stderr)
sys.exit(1)
search_pdb_with_keyword(pdb_file, keyword)
想象一下,如果你有多个参数,每个参数都有自己特定的要求,那么你就得写很多if
条件,这样既繁琐又容易出错。
这时候argparse
就派上用场了,它可以帮助你定义程序接受哪些参数,以及argparse
如何验证这些参数。
from argparse import ArgumentParser
parser = ArgumentParser(description="PDB keyword search program.")
parser.add_argument("pdb_file", type=file, help="A PDB file as input.")
parser.add_argument("keyword", choices=("ATOM", "HETATM"), help="Keyword to search for")
# argparse will validate the user's arguments for you, checking if two arguments are
# specified and if the first argument is an existing file and if the second argument
# is either ATOM or HETATM
args = parser.parse_args()
search_pdb_with_keyword(args.pdb_file, args.keyword)
如果用户错误地运行了程序,比如说:
$ python pdb_search.py pdb_file # lacking the keyword
就会弹出一个错误:
$ python pdb_search.py
usage: pdb_search.py [-h] pdb_file {ATOM,HETATM}
pdb_search.py: error: too few arguments
这个错误会告诉你程序需要多少个参数,以及这些参数是什么。
它甚至会为你格式化使用信息:
$ python pdb_search.py -h
usage: pdb_search.py [-h] pdb_file {ATOM,HETATM}
PDB keyword search program.
positional arguments:
pdb_file A PDB file as input.
{ATOM,HETATM} Keyword to search for
optional arguments:
-h, --help show this help message and exit
如果你想了解更多关于如何使用它以及它如何与你的使用场景相关的信息,建议你真的去阅读argparse
的文档。
你也可以参考其他人的回答,作为我代码中虚拟函数search_pdb_with_keyword
的实现。