如果您的答案是:给py脚本运行权限,并且加上 #!/usr/bin/env python 的话,请您继续往下看。
今天在PyPI上发现一个包pyfasta,pip安装之后,可以在命令行下输入pyfasta直接运行
root$ pyfasta extract --help
Usage: extract some sequences from a fasta file. e.g.:
pyfasta extract --fasta some.fasta --header at2g26540 at3g45640
Options:
-h, --help show this help message and exit
--fasta=FASTA path to the fasta file
安装包内只有四个py文件( __init__.py, fasta.py, records.py, split_fasta.py)
这是怎么做到的?
pyfasata 可以指定不同的action(下述的四个),接受不同的参数,从而实现不同的功能
这样要怎么做?
可以结合 __init__.py 的内容,我有点头绪,但又不是完全懂,已付__init__.py的代码
`
root$pyfasta
available actions:
`extract`: extract sequences from a fasta file
`info`: show info about the fasta file and exit.
`split`: split a large fasta file into separate files
and/or into K-mers.
`flatten`: flatten a fasta file inplace so that later`
import sys
from .fasta import Fasta, complement, DuplicateHeaderException
from .records import *
from .split_fasta import split
import optparse
def main():
help = """
available actions:
`extract`: extract sequences from a fasta file
`info`: show info about the fasta file and exit.
`split`: split a large fasta file into separate files
and/or into K-mers.
`flatten`: flatten a fasta file inplace so that later
command-line (and programmattic) access via
pyfasta will use the inplace flattened version
rather than creating another .flat copy of the
sequence.
to view the help for a particular action, use:
pyfasta [action] --help
e.g.:
pyfasta extract --help
"""
if len(sys.argv) == 1:
print(help)
sys.exit()
action = sys.argv[1]
sglobals = globals()
if not action in sglobals:
print("%s not a valid action" % action)
print(help)
sys.exit()
globals()[action](sys.argv[2:])
def info(args):
"""
>>> info(['tests/data/three_chrs.fasta'])
<BLANKLINE>
tests/data/three_chrs.fasta
===========================
>chr3 length:3600
>chr2 length:80
>chr1 length:80
<BLANKLINE>
3760 basepairs in 3 sequences
"""
parser = optparse.OptionParser("""\
print headers and lengths of the given fasta file in order of length. e.g.:
pyfasta info --gc some.fasta""")
parser.add_option("-n", "--n", type="int", dest="nseqs",
help="max number of records to print. use -1 for all",
default=20)
parser.add_option("--gc", dest="gc", help="show gc content",
action="store_true", default=False)
options, fastas = parser.parse_args(args)
if not (fastas):
sys.exit(parser.print_help())
import operator
for fasta in fastas:
f = Fasta(fasta)
info = [(k, len(seq)) for k, seq in f.items()]
total_len = sum(l for k, l in info)
nseqs = len(f)
if options.nseqs > -1:
info = sorted(info, key=operator.itemgetter(1, 0), reverse=True)
info = info[:options.nseqs]
else:
info.sort()
print("\n" + fasta)
print("=" * len(fasta))
for k, l in info:
gc = ""
if options.gc:
seq = str(f[k]).upper()
g = seq.count('G')
c = seq.count('C')
gc = 100.0 * (g + c) / float(l)
gc = "gc:%.2f%%" % gc
print((">%s length:%i" % (k, l)) + gc)
if total_len > 1000000:
total_len = "%.3fM" % (total_len / 1000000.)
print()
print("%s basepairs in %i sequences" % (total_len, nseqs))
def flatten(args):
"""
>>> flatten(['tests/data/three_chrs.fasta'])
"""
parser = optparse.OptionParser("""flatten a fasta file *inplace* so all later access by pyfasta will use that flattend (but still viable) fasta file""")
_, fasta = parser.parse_args(args)
for fa in fasta:
f = Fasta(fa, flatten_inplace=True)
def extract(args):
"""
>>> extract(['--fasta', 'tests/data/three_chrs.fasta', 'chr2'])
TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT
"""
parser = optparse.OptionParser("""extract some sequences from a fasta file. e.g.:
pyfasta extract --fasta some.fasta --header at2g26540 at3g45640""")
parser.add_option("--fasta", dest="fasta", help="path to the fasta file")
parser.add_option("--header", dest="header", help="include headers", action="store_true", default=False)
parser.add_option("--exclude", dest="exclude", help="extract all sequences EXCEPT those listed", action="store_true", default=False)
parser.add_option("--file", dest="file", help=\
"if this flag is used, the sequences to extract" \
" are read from the file specified in args"
, action="store_true", default=False)
parser.add_option("--space", dest="space", action="store_true", help=\
"use the fasta identifier only up to the space as the key",
default=False)
options, seqs = parser.parse_args(args)
if not (options.fasta and len(seqs)):
sys.exit(parser.print_help())
key_fn = (lambda k: k.split()[0]) if options.space else None
f = Fasta(options.fasta, key_fn=key_fn)
if options.file:
seqs = (x.strip() for x in open(seqs[0]))
if options.exclude:
seqs = sorted(frozenset(iter(f.keys())).difference(seqs))
for seqname in seqs:
seq = f[seqname]
if options.header:
print(">%s" % seqname)
print(seq)
if __name__ == "__main__":
main()
sys.argv를 사용하여 달성
Python에는 위에서 사용되는 optparse라는 자체 패키지가 포함되어 있습니다.
으아악현재 구현된 새 버전은 argparse입니다.
타사 패키지인 Clint, Click, docopt, Plac도 있습니다. Cliff.
위에 언급된 타사 패키지는 모두 내장 패키지보다 사용하기 쉬워야 합니다(내장 패키지에는 너무 많은 코드가 필요함).
비교 기사를 살펴보세요. Python 명령줄 구문 분석 라이브러리 - Argparse, Docopt 및 Click
타사 패키지 중 Click과 docopt가 더 좋을 것입니다. 다른 패키지는 현재 알려지지 않았습니다.
과 같은 Python 명령을 실행하는 방법에 대한 이 기사를 참조하는 것이 좋습니다.자세한 내용은 여기에서 명령줄 애플리케이션을 참조하세요
hello 스크립트처럼 hello를 실행하는 방법은 다음과 같습니다. 응? Python의 setuptools
를 살펴보거나 ls -l
그런 다음 명령줄에서 python hello.py hello를 실행하면 출력 결과는 다음과 같습니다.
으아악물론 명령줄이
python
으로 시작하지 않는다는 것을 발견했을 수도 있습니다. 이는 패키지가 설치 프로세스 중에 사용자 정의 명령을 추가했기 때문입니다. (Ubuntu-14.04
그것이 맞는지 확인하세요. 유효) 명령줄에alias pyhello="python /path/hello.py"
을 입력하면pyhello
과 같은 명령이 시스템에 추가됩니다. 이를 입력하는 것은python /path/hello.py
을 실행하는 것과 같습니다.글쎄요, 위의 원칙은 이미 알려져 있죠. 프로그램의 매개변수를 판단하면 됩니다. 그렇지 않나요
OK
?4
,40
는 괜찮다고 말하지 마세요...명령줄을 최대한 활용하고 싶다면
Python
getopt
이라는 표준 패키지가 있는데 매우 유용합니다.행운을 빕니다.