2017-02-17 4 views
4

У меня возникла аналогичная проблема с другим пользователем @AMisra, опубликованным некоторое время назад, но не получившим окончательного ответа. Проблема в том, что я использую сторонний код и не могу его слишком сильно изменить. У меня есть функция, которая много раз вызывается в коде для создания подпроцесса, записи данных в stdin и последующего чтения. Это просто висит на этой линииpopen с python чтение и запись блоков в python2.7

line = self.classifier.stderr.readline()

Следует заметить, что я не могу использовать communicate: поскольку func2(classifier, vectors) должен вызываться несколько раз, он вызывает исключение.

import subprocess 
import paths 
import os.path 

class CRFClassifier: 
    def __init__(self, name, model_type, model_path, model_file, verbose): 
     self.verbose = verbose 
     self.name = name 
     self.type = model_type 
     self.model_fname = model_file 
     self.model_path = model_path 

     if not os.path.exists(os.path.join(self.model_path, self.model_fname)): 
      print 'The model path %s for CRF classifier %s does not exist.' % (os.path.join(self.model_path, self.model_fname), name) 
      raise OSError('Could not create classifier subprocess') 


     self.classifier_cmd = '%s/crfsuite-stdin tag -pi -m %s -' % (paths.CRFSUITE_PATH, 
          os.path.join(self.model_path, self.model_fname)) 
#  print self.classifier_cmd 
     self.classifier = subprocess.Popen(self.classifier_cmd, shell = True, stdin = subprocess.PIPE, stderr = subprocess.PIPE) 

     if self.classifier.poll(): 
      raise OSError('Could not create classifier subprocess, with error info:\n%s' % self.classifier.stderr.readline()) 

     #self.cnt = 0 


    def classify(self, vectors): 
#  print '\n'.join(vectors) + "\n\n" 

     self.classifier.stdin.write('\n'.join(vectors) + "\n\n") 

     lines = [] 
     line = self.classifier.stderr.readline() 
     while (line.strip() != ''): 
#   print line 
      lines.append(line) 
      line = self.classifier.stderr.readline() 


     if self.classifier.poll(): 
      raise OSError('crf_classifier subprocess died') 

     predictions = [] 
     for line in lines[1 : ]: 
      line = line.strip() 
#   print line 
      if line != '': 
       fields = line.split(':') 
#    print fields 
       label = fields[0] 
       prob = float(fields[1]) 
       predictions.append((label, prob)) 

     seq_prob = float(lines[0].split('\t')[1]) 

     return seq_prob, predictions 


    def poll(self): 
     """ 
     Checks that the classifier processes are still alive 
     """ 
     if self.classifier is None: 
      return True 
     else: 
      return self.classifier.poll() != None 

Объект классификатор создается для входного файла, который представляет собой документ с перечнем предложений и в момент создания он также выполняет внешнюю команду с этим списком предложений. Затем в отдельной функции обрабатывается каждое предложение, дающее отдельный вектор для каждого предложения. Этот новый вектор передается функции классификации.

def func2(): 
    classifier=create a classifier object for an input file, this executes the external command 
    for sentence in sentences: 
     vectors=process(sentence)# some external function 
     classifier.classify(features) 

ответ

0

Initialize self.classifier в classify методе вместо конструктора, а также использовать Popen(). Также необходимо использовать stdout вместо stderr.

Смежные вопросы