Как вызвать функцию типа генератора с функцией нетипа в цикле? - PullRequest
1 голос
/ 17 февраля 2012

У меня есть функция генератора getElements в классе Reader (), которая выдает все элементы из XML-файла.Я также хочу иметь функцию getFeatures, которая возвращает только элементы с тегом функции.

Как я пытался это сделать, чтобы иметь флаг featuresOnly, установленный в True, когда вызывается getFeatures, а в getFeatures вызывается self.getElements, например:

def getFeatures(self):
    self.getFeaturesOnly = True
    self.getElements()

Таким образом, в getElements() Мне нужно только сделать

def getElements(self):
    inFile = open(self.path)
    for element in cElementTree.iterparse(inFile):
        if self.getFeaturesOnly == True:
            if element.tag == 'feature':
                yield element
        else:
            yield element
     inFile.close()

Однако, когда я делаю это и запускаю его

 features = parseFeatureXML.Reader(filePath)
 for element in features.getFeatures():#
       print element

, я получаю: TypeError: объект 'NoneType' не повторяется Это потому, что getFeaturesне содержит доходности.Теперь способ, которым я знаю, как решить эту проблему, - это скопировать код getElements в getFeatures и использовать только

if elementFunctions.getElmentTag(element) == 'feature':

в функции getFeatures (), но я не буду дублировать какой-либо код.Так как же я смогу сохранить функцию генератора и использовать другую функцию, в которой я только определяю, какой тег я хотел бы получить?

Ответы [ 2 ]

3 голосов
/ 17 февраля 2012

Перво-наперво: У вас есть эта ошибка, потому что вы не возвращаете генератор

Это означает, что вы должны изменить:

def getFeatures(self):
    self.getFeaturesOnly = True
    self.getElements()

с:

def getFeatures(self):
    self.getFeaturesOnly = True
    return self.getElements()    # returning the generator

Выяснил это, ТБХ. Я бы не стал так проектировать свой класс Reader().

Я бы позволил getElement получить все элементы:

def getElements(self):
    inFile = open(self.path)
    for element in cElementTree.iterparse(inFile):
        yield element
    inFile.close()

А затем getFeatures() выполните фильтрацию:

def getFeatures(self):
    for element in self.getElements():
        if element.tag == 'feature':
            yield element
2 голосов
/ 17 февраля 2012

Причина, по которой вы получаете TypeError, заключается не в том, что getFeatures не содержит доходности, а в том, что getFeatures ничего не возвращает . Если вы хотите, чтобы getFeatures возвратил итератор, возвращенный getElements, вы должны использовать return:

def getFeatures(self):
    self.getFeaturesOnly = True
    return self.getElements()

Пока вы занимаетесь этим, вам действительно не следует делать if expr == True; просто сделайте if expr, который работает, даже если expr является верным (концепция), но не True (объект). Тем не менее, вместо включения поддержки только для функций в getElements, более распространенный подход сделать это в самом getFeatures, вот так:

def getFeatures(self):
    for element in self.getElements():
        if element.tag == 'feature':
            yield element

def getElements(self):
    inFile = open(self.path)
    for element in cElementTree.iterparse(inFile):
        yield element
    inFile.close()
...