Попытка пройти (обойти) каталог esp32 с помощью микропитона

#esp32 #micropython

Вопрос:

 ```
# try.py
import uos
dir = 16384

def walk(t): # recursive function
    print('-',t)
    w = uos.ilistdir(t)
    for x in w:
        L = list(x)
        print(L[0], L[1], L[3])
        if L[1] == dir:
            walk(L[0])
        else:
            return
    

z = uos.ilistdir()
for x in z:
    L = list(x)
    print(L[0], L[1], L[3])
    if L[1] == dir:
        walk(L[0])

```
 

Код останавливается с ошибкой в строке 7, с ошибкой:

Выход:

Traverse.py 32768 773

boot.py 32768 139

lib 16384 0

-либ

один 16384 0

-один

Обратная связь (последний последний звонок):

Файл «stdin», строка 21, в

Файл «stdi>», строка 12, в прогулке

Файл »

Ошибка: [Ошибка 2] ДОСТАТОЧНО

Структура каталогов является:

либ

 one

    two

        three

    three.py
 

boot.py

main.py

one.py

Traverse.py

Кажется, что он останавливается на каталоге, в котором нет файлов

Комментарии:

1. Так в чем же вопрос? Вы не знаете, как обрабатывать исключение try...catch или что-то еще?

2. Почему я получаю сообщение об ошибке ?

Ответ №1:

У меня нет ESP для тестирования, но здесь есть некоторые проблемы:

  • вы не должны возвращаться, если запись является файлом, но вместо этого продолжайте, вот почему она останавливается слишком рано
  • вы должны пропустить текущий и родительский каталог, чтобы избежать бесконечной рекурсии
  • при рекурсии вы должны добавить верхний каталог, что, вероятно, является причиной ошибки, т. е. ваш код вызывает walk('two') , но такого каталога нет, он должен быть one/two )
  • вы можете использовать функцию walk в текущем каталоге, чтобы последний бит, в котором вы дублируете реализацию, не требовался.

Дополнительно:

  • итерация ilistdir возвращает tuple s, которые также могут быть проиндексированы, поэтому нет необходимости преобразовывать их в list
  • и передача коллекций print напрямую также работает, нет необходимости в отдельных print(x[0], x[1], ... )

Adpatation, с немного другой печатью полных путей, чтобы было легче следовать:

 import uos

dir_code = 16384

def walk(t):
    print('-', t)
    for x in uos.ilistdir(t):
        print(x)
        if x[1] == dir_code and x[0] != '.' and x[0] != '..':
            walk(t   '/'   x[0])
    
walk('.')
 

Это все равно будет печатать каталоги дважды, добавляя все, что индексирование затрудняет чтение. Адаптация с однократной распаковкой кортежей и печатью каталогов:

 import uos

dir_code = 16384

def walk(top):
    print(top)
    for name, code, _ in uos.ilistdir(top):
        if code != dir_code:
            print(top   '/'   name)
        elif name not in ('.', '..'):
            walk(top   '/'   name)
    
walk('.')
 

Комментарии:

1. Первый код работал нормально, но (как вы сказали) он дважды печатал Каталоги. во втором обнаружилась ошибка: Файл «<stdin>», строка 7, в ошибке ValueError: слишком много значений для распаковки (ожидается 3), Но я особенно благодарю вас за ваши исправления и объяснение ошибок и упрощений моего кода. Хотя я профессионально занимаюсь кодированием в течение последних 60 лет, я не являюсь опытным программистом на Python.

2. @user1530405 возможно, кортеж, возвращаемый ilistdir, имеет 4 значения, и в этом случае вы бы использовали for name, code, _, __ in uos.ilistdir(top): что-то вроде

3. Да, это и есть ответ. Спасибо