Каков правильный подход Python, чтобы избежать добавления в список в этом скрипте? - PullRequest
0 голосов
/ 05 мая 2020

Я новичок в Python, но я прочитал руководство w3schools перед тем, как начать.

Недавний поиск в Интернете привел меня к этому полезному скрипту, который создает представление файла JSON дерево.

#!/usr/bin/env python

import os
import errno

def path_hierarchy(path):
    hierarchy = {
        'type': 'folder',
        'name': os.path.basename(path),
        'path': path,
    }

    try:
        hierarchy['children'] = [
>>>         path_hierarchy(os.path.join(path, contents))
            for contents in os.listdir(path)
        ]
    except OSError as e:
        if e.errno != errno.ENOTDIR:
            raise

        if os.path.basename(path).endswith('doc') or os.path.basename(path).endswith('docx'):
            hierarchy['type'] = 'file'
        else:
+++         hierarchy = None


    return hierarchy

if __name__ == '__main__':
    import json
    import sys

    try:
        directory = sys.argv[1]
    except IndexError:
        directory = "/home/something/something"

    print(json.dumps(path_hierarchy(directory), indent=4, sort_keys=True))

У меня 2 вопроса:

  1. Почему в позиции, отмеченной ">>>", оператор FOR не предшествует вызову метод path_hierarchy ?

  2. Как мне избежать добавления объекта hierarchy для файла, который не является ни "do c", ни " docx "? Я экспериментировал с установкой для объекта иерархии значения Нет в строке с пометкой «+++», но это просто возвращало «ноль» в выводе JSON. Я бы хотел, чтобы запись вообще отсутствовала, если текущий элемент не является папкой или типом, разрешенным моим тестом (в данном случае либо 'do c', либо 'docx')

1 Ответ

1 голос
/ 05 мая 2020

Для 1 это понимание списка. Они используются для создания списка из другого списка.


Для 2, на самом деле, проблема в том, что вы не хотите, чтобы None s добавлялись к hierarchy['children']. Это можно сделать несколькими разными способами, но для этого я бы просто изменил вашу строку >>>.

Если у вас Python 3.8+, вы можете использовать выражение присваивания (:=) и добавьте проверку if к пониманию списка:

hierarchy['children'] = [
    child := path_hierarchy(os.path.join(path, contents))
    for contents in os.listdir(path)
    if child  # Only add a child if the child is truthy (Not None)
]

Без Python 3.8 вам необходимо преобразовать этот фрагмент в полный for l oop:

hierarchy['children'] = []
for contents in os.listdir(path):
    child = path_hierarchy(os.path.join(path, contents))
    if child:
        hierarchy['children'].append(child)

Оба, по сути, эквивалентны.

Вывод здесь состоит в том, чтобы просто проверить, что является дочерним элементом, прежде чем добавлять его в дерево.

...