python2.7 - 怎样才能让python 脚本像shell命令一样直接运行并可以接收参数?
天蓬老师
天蓬老师 2017-04-17 17:39:57
0
3
558

如果您的答案是:给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)

  1. 这是怎么做到的?

  2. 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()
天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

모든 응답(3)
Ty80

sys.argv를 사용하여 달성

伊谢尔伦

Python에는 위에서 사용되는 optparse라는 자체 패키지가 포함되어 있습니다.
현재 구현된 새 버전은 argparse입니다.
타사 패키지인 Clint, Click, docopt, Plac도 있습니다. Cliff.
위에 언급된 타사 패키지는 모두 내장 패키지보다 사용하기 쉬워야 합니다(내장 패키지에는 너무 많은 코드가 필요함).
비교 기사를 살펴보세요. Python 명령줄 구문 분석 라이브러리 - Argparse, Docopt 및 Click

으아악

타사 패키지 중 Click과 docopt가 더 좋을 것입니다. 다른 패키지는 현재 알려지지 않았습니다.
자세한 내용은 여기에서 명령줄 애플리케이션을 참조하세요
hello 스크립트처럼 hello를 실행하는 방법은 다음과 같습니다. 응? Python의 setuptools
를 살펴보거나 ls -l

과 같은 Python 명령을 실행하는 방법에 대한 이 기사를 참조하는 것이 좋습니다.
小葫芦

1. 어떻게 하나요?
Python 명령줄 자체는 매개변수 추가를 지원합니다. 명령줄의 모든 매개변수(py 파일 이름 자체 포함)는 sys.argv를 사용하여 얻을 수 있습니다.

으아악

그런 다음 명령줄에서 python hello.py hello를 실행하면 출력 결과는 다음과 같습니다.

으아악

물론 명령줄이 python으로 시작하지 않는다는 것을 발견했을 수도 있습니다. 이는 패키지가 설치 프로세스 중에 사용자 정의 명령을 추가했기 때문입니다. (Ubuntu-14.04 그것이 맞는지 확인하세요. 유효) 명령줄에 alias pyhello="python /path/hello.py"을 입력하면 pyhello과 같은 명령이 시스템에 추가됩니다. 이를 입력하는 것은 python /path/hello.py을 실행하는 것과 같습니다.

2.…어떻게 할까요?

글쎄요, 위의 원칙은 이미 알려져 있죠. 프로그램의 매개변수를 판단하면 됩니다. 그렇지 않나요OK? 4, 40는 괜찮다고 말하지 마세요...

3.추가

명령줄을 최대한 활용하고 싶다면 Pythongetopt이라는 표준 패키지가 있는데 매우 유용합니다.
행운을 빕니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿