2014-08-29 104 views
0

我有这个文件的问题。当我启动它时,我收到第24行的错误。UnboundLocal错误文件

UnboundLocal Error : local variable 'file_out' referenced before assignment. 

有关如何更正它的任何建议将不胜感激。我不得不说,我是一个完整的Python的noob,并没有自己写这个。

#!/usr/local/python 

import sys, getopt 
import os 

usage="python correct_mol2.py -i 2qab_ligand.mol2 -o 2qab_ligand_new.mol2\n" 

def main(argv): 

    try: 
     opts,args = getopt.getopt(sys.argv[1:],'hi:o:') 
    except getopt.GetoptError: 
     sys.exit(2) 

    for opt, arg in opts: 
     if opt == '-h': 
      print usage 
      sys.exit() 
     elif opt == '-i': 
       file_in = arg 
     elif opt == '-o': 
      file_out = arg 
    x=0 
    fout=file("%s"%file_out,"w") 
    for line in file(file_in): 
#  print line 
     if line.find("@<TRIPOS>BOND") >= 0: 
      x=0 
     if x==0: 
      fout.write(line) 
     if x==1: 
      if line[47:49] == '35' : 
       fout.write(line[:47]+"Br"+line[49:]) 
       continue 
      if line[47:49] == '17' : 
       fout.write(line[:47]+"Cl"+line[49:]) 
       continue 
      if line[47:48] == '9' : 
       fout.write(line[:47]+"F"+line[48:]) 
       continue 
      if (line[47] == 'H' and line[48] ==' ') or line[47] == 'F' or line[47:49] == 'Br' or line[47:49] == 'Cl' : 
       fout.write(line) 
       continue 
      else: 
       fout.write(line[:48]+"."+line[48:54]+line[55:]) 
     if line.find("@<TRIPOS>ATOM") >= 0: 
      x=1 
    fout.close() 

main(sys.argv) 

回答

1

file_out说法是只有集如果-o参数设置。

您需要将for opt, arg in opts:循环之前可能设置默认:

file_out = 'default_filename' 

如果-o意味着是一个强制性的选择,你需要明确地测试选择缺席。

您的代码的其他意见:

  • 使用argparse代替; optparse已被弃用,它的继任者更加灵活多变。

  • file_out在设置时已经是一个字符串。不需要使用字符串格式;您可以直接将其传递给open()(而不是file(),也不赞成使用)。如果您使用的文件对象为context manager,然后它会自动关闭你:

    with open(file_out, "w") as fout, open(file_in) as fin: 
        for line in fin: 
    
  • 您可以使用文件对象作为一个迭代器,这意味着你可以提前文件对象,并获得更多的线随着解析状态的变化,for循环。用它来检测Tripos MOL2记录。

    Tripos MOL2 data records使用制表符或空格分隔行;将你的行分割成列,然后挑出特定的列来映射替换值。这比切片行到特定的列少了很多脆弱:

    map = {'35': 'Br', '17': 'Cl', '9': 'F'} 
    # when we encounter a mapped value, make it easier on ourselves 
    # and map those back to themselves 
    map.update((v: v) for v in map.values()) 
    
    section = None 
    for line in fin: 
        if line[0] == '@': 
         # new section 
         section = line.strip().rpartition('>')[-1] 
         fout.write(line) 
         continue 
    
        if section != 'ATOM': 
         fout.write(line) 
         continue 
    
        # parse the ATOM section 
        for line in fin: 
         if line[0] == '@': # section end, we are done 
          section = line.strip().rpartition('>')[-1] 
          fout.write(line) 
          break 
    
         # atom data lines are whitespace separated 
         row = line.split() 
    
         # I'm assuming column 7 is the value you are replacing; adjust as required 
         row[7] = map.get(row[7], '.') 
    
         # re-join line with tabs, write out 
         fout.write('\t'.join(row) + '\n') 
    
+0

非常感谢您为您详细的答复。 主要问题是我真的不懂编程。我真的不知道要替换什么以及如何替换。 我很惭愧地问你,但你能否重写脚本,所以我只需要复制它并使其工作? 我是一名药物化学科学家,因此它将帮助我的研究专注于癌症。 – 2014-09-01 07:34:58

+0

@XavierDrozak:我只做了一个有根据的猜测,可能会做些什么来改进您的代码。我无法完全为您重新编写您的代码;我无法访问您拥有的数据,也无法为您测试。找一个能编程的人,或者可以教你在附近进行编程,在一个更适合指导的环境中进行编程。我可以通过在线辅导计划获得(请参阅我的个人资料)。祝你好运! – 2014-09-01 07:47:31