Python os.walk и символические ссылки
Исправляя ответ одного пользователя на AskUbuntu, я обнаружил небольшую проблему. Сам код прост: os.walk, рекурсивно получит сумму всех файлов в каталоге.
Но это ломается на символические ссылки:
$ python test_code2.py $HOME
Traceback (most recent call last):
File "test_code2.py", line 8, in <module>
space += os.stat(os.path.join(subdir, f)).st_size
OSError: [Errno 2] No such file or directory: '/home/xieerqi/.kde/socket-eagle'
Тогда возникает вопрос: как мне сказать python игнорировать эти файлы и не суммировать их?
Решение:
Как предложено в комментариях, я добавил os.path.isfile()
проверьте и теперь он работает отлично и дает правильный размер для моего домашнего каталога
$> cat test_code2.py
#! /usr/bin/python
import os
import sys
space = 0L # L means "long" - not necessary in Python 3
for subdir, dirs, files in os.walk(sys.argv[1]):
for f in files:
file_path = os.path.join(subdir, f)
if os.path.isfile(file_path):
space += os.stat(file_path).st_size
sys.stdout.write("Total: {:d}\n".format(space))
$> python test_code2.py $HOME
Total: 76763501905
2 ответа
Как уже упоминал Антти Хаапала в комментарии, скрипт не разбивается на символические ссылки, а на битые символические ссылки. Одним из способов избежать этого, взяв существующий сценарий в качестве отправной точки, является использование try/except
:
#! /usr/bin/python2
import os
import sys
space = 0L # L means "long" - not necessary in Python 3
for root, dirs, files in os.walk(sys.argv[1]):
for f in files:
fpath = os.path.join(root, f)
try:
space += os.stat(fpath).st_size
except OSError:
print("could not read "+fpath)
sys.stdout.write("Total: {:d}\n".format(space))
Как побочный эффект, он дает вам информацию о возможных неработающих ссылках.
Да, os.path.isfile
это путь Однако следующая версия может быть более эффективной памяти.
for subdir, dirs, files in os.walk(sys.argv[1]):
paths = (os.path.join(subdir, f) for f in files)
space = sum(os.stat(path).st_size for path in paths if os.path.isfile(path))