2016-08-05 26 views
0

Dies ist mein erster Versuch, Kommandozeilenargumente außer dem schnellen und schmutzigen sys.argv[] zu verwenden und ein "richtigeres" Python-Skript zu schreiben. Aus irgendeinem Grund, den ich jetzt nicht herausfinden kann, scheint es dagegen zu sein, dass ich versuche, die Eingabedatei über die Befehlszeile zu verwenden.Fehlerbehandlungsdatei von der Befehlszeile mit biopython SeqIO

Das Skript ist dazu gedacht, eine Eingabedatei, einige numerische Indizes zu nehmen und dann einen Teilbereich der Datei auszuschneiden, allerdings bekomme ich immer Fehler, dass die Variable, die ich der Datei übergeben habe, ist nicht definiert:

[email protected]:~/Documents/Warwick/PhD/Scripts$ python slice_genbank.py --input PAU_06042014.gbk -o test.gbk -s 3907329 -e 3934427 
Traceback (most recent call last): 
    File "slice_genbank.py", line 70, in <module> 
    sub_record = record[start:end] 
NameError: name 'record' is not defined 

Hier ist der Code, wo liege ich falsch? (Ich bin sicher, dass seine einfache):

#!/usr/bin/python 

# This script is designed to take a genbank file and 'slice out'/'subset' 
# regions (genes/operons etc.) and produce a separate file. 

# Based upon the tutorial at http://biopython.org/DIST/docs/tutorial/Tutorial.html#htoc44 

# Set up and handle arguments: 
from Bio import SeqIO 
import getopt 


def main(argv): 
    record = '' 
    start = '' 
    end = '' 
    try: 
     opts, args = getopt.getopt(argv, 'hi:o:s:e:', [ 
                'help', 
                'input=', 
                'outfile=', 
                'start=', 
                'end=' 
                ] 
          ) 
     if not opts: 
      print "No options supplied. Aborting." 
      usage() 
      sys.exit(2) 
    except getopt.GetoptError: 
     print "Some issue with commandline args.\n" 
     usage() 
     sys.exit(2) 

    for opt, arg in opts: 
     if opt in ("-h", "--help"): 
      usage() 
      sys.exit(2) 
     elif opt in ("-i", "--input"): 
      filename = arg 
      record = SeqIO.read(arg, "genbank") 
     elif opt in ("-o", "--outfile"): 
      outfile = arg 
     elif opt in ("-s", "--start"): 
      start = arg 
     elif opt in ("-e", "--end"): 
      end = arg 
    print("Slicing " + filename + " from " + str(start) + " to " + str(end)) 

def usage(): 
    print(
""" 
This script 'slices' entries such as genes or operons out of a genbank, 
subsetting them as their own file. 

Usage: 
python slice_genbank.py -h|--help -i|--input <genbank> -o|--output <genbank> -s|--start <int> -e|--end <int>" 

Options: 

-h|--help  Displays this usage message. No options will also do this. 
-i|--input  The genbank file you which to subset a record from. 
-o|--outfile The file name you wish to give to the new sliced genbank. 
-s|--start  An integer base index to slice the record from. 
-e|--end  An integer base index to slice the record to. 
""" 
    ) 

#Do the slicing 
sub_record = record[start:end] 
SeqIO.write(sub_record, outfile, "genbank") 

if __name__ == "__main__": 
main(sys.argv[1:]) 

Es ist auch möglich, es gibt ein Problem mit der SeqIO.write Syntax, aber ich habe nicht so weit, daß noch bekommt.

EDIT:

auch vergessen zu erwähnen, dass, wenn ich `record = SeqIO.read ("file.gbk", "Genbank") verwenden und die Dateinamen direkt in das Skript schreiben, es funktioniert einwandfrei.

+1

können Sie den Eintrag bearbeiten, um die richtige Vertiefung zu haben? Soweit ich das beurteilen kann, ist "record" nur in der 'main()' Methode definiert, daher hat das Hauptprogramm keine Kenntnis darüber. – Markus

+0

Ah Entschuldigung, ja, ich habe nicht bemerkt, dass es den Einzug nicht erhalten hat. Will edit –

+0

OK Ich denke, dass ist entsprechend bearbeitet und eingerückt. Ich denke, dass Sie gut auf etwas mit Subrecordanruf sein können, der später im Skript ist. Ich denke immer noch in bash ich denke ... –

Antwort

1

Wie in den Kommentaren gesagt, Ihre Variable records wird nur in der Methode main() definiert (das gleiche für start und end wahr ist), so ist es für den Rest des Programms nicht sichtbar. Sie können entweder die Werte wie folgt zurück:

def main(argv): 
    ... 
    ... 
    return record, start, end 

Ihr Anruf zu main() kann dann wie folgt aussehen:

record, start, end = main(sys.argv[1:]) 

Alternativ können Sie Ihre Haupt-Funktionalität in die main Funktion bewegen (wie du).

(Eine andere Möglichkeit ist es, die Variablen im Hauptprogramm und die Verwendung der global Schlüsselwort in Ihrer Funktion zu definieren, ist dies jedoch nicht empfohlen.)