с path.open ('r', encoding = "utf-8") в качестве файла: AttributeError: объект 'generator' не имеет атрибута 'open' - PullRequest
0 голосов
/ 28 января 2020

Я не совсем уверен, как получить доступ к именам файлов и сделать необходимые изменения, как написано в сценарии? Я пытаюсь получить доступ к некоторым файлам, которые находятся внутри папок. Я также хочу использовать эти файлы, как показано в строке

item = etree.Element('language', attrib={"lang": path.parent.name, "status": "Reviewed"})

import pathlib
import functools
import operator
import lxml.etree as etree
from lxml.builder import ElementMaker

ATTRIB = {"xsi": "test.xsd", "xmlns": "http://www.w3.org/2001/XMLSchema-instance"}



def is_element(node):
    return hasattr(node, 'attrib') and 'name' in node.attrib


def create_plural(item):
    pass



def main():
    cwd = pathlib.Path.cwd()
    directories = list(filter(lambda path: path.is_dir(), cwd.iterdir()))
    langs = [path.name for path in directories]
    files = map(operator.methodcaller('glob', '*.xml'), directories)
    #trees = dict.fromkeys(unique_names, dict())


    for path in files:
        with path.open('r', encoding="utf-8") as file:
            tree = etree.parse(file)
        root = tree.getroot()
        name = xml_path.with_suffix('').with_suffix('').name
        out_tree = trees[name]



        for child in filter(is_element, root):
            id = child.attrib['name']
            text = child.text
            if id not in out_tree:
                out_tree[id] = list()
            item = etree.Element('language', attrib={"lang": path.parent.name, "status": "Reviewed"})
            if child.tag == "plurals":
                item.text = create_plural(child)
            else:
                item.text = etree.CDATA(text)
            out_tree[id].append(item)



if __name__ == '__main__':
    main()



    #name = '{}.strings.xml'.format(xml_file.with_suffix('').name)  # name of the file
        #out_p = out_path / lang / name  # path of the output file where it should be located
        #out_p.parent.resolve().mkdir(parents=True, exist_ok=True)  # make directory
        #text = etree.tostring(root, xml_declaration=True, pretty_print=True, encoding="utf-8")
        #with out_p.open('wb') as file:
        #    file.write(text) ```



Ответы [ 2 ]

0 голосов
/ 28 января 2020

Проблема заключается в следующем:

files = map(operator.methodcaller('glob', '*.xml'), directories)

glob возвращает генератор путей, поэтому file - это не последовательность путей, а последовательность последовательностей путей.

Вам нужно либо itertools.chain.from_iterable целиком в одну последовательность, либо использовать вложенную l oop. Или используйте сострадание, чтобы развернуть все это. map имеет большой смысл, когда у вас уже есть функция, выполняющая то, что вам нужно, но это не тот случай, поэтому понимание предпочтительнее:

files = (
    f
    for d in directories
    for f in d.glob('*.xml')
)
0 голосов
/ 28 января 2020

Вместо:

with path.open('r', encoding="utf-8") as file:
    tree = etree.parse(file)

Вы можете передать имя файла (строку) непосредственно для разбора:

tree = etree.parse(path)

path в вашем примере это строка, поэтому она не иметь функцию open.

Возможно, вы имели в виду:

with open(path, 'r', encoding="utf-8") as file:
    tree = etree.parse(file)

Если вы пытаетесь найти xml имен файлов в текущем каталоге:

[f for f in os.listdir('.') if f.endswith('.xml')]
...