Potrzebuję chodzącego system plików, który mógłbym zignorować przechodzenie przez katalogi, które chcę pozostawić nietknięty, w tym wszystkie podkatalogi poniżej tego oddziału. Os.walk i os.path.walk po prostu tego nie robią.Spacer w języku Python, który może zignorować katalogi
Odpowiedz
Więc zrobiłem to home-role walker funkcję:
import os
from os.path import join, isdir, islink, isfile
def mywalk(top, topdown=True, onerror=None, ignore_list=('.ignore',)):
try:
# Note that listdir and error are globals in this module due
# to earlier import-*.
names = os.listdir(top)
except Exception, err:
if onerror is not None:
onerror(err)
return
if len([1 for x in names if x in ignore_list]):
return
dirs, nondirs = [], []
for name in names:
if isdir(join(top, name)):
dirs.append(name)
else:
nondirs.append(name)
if topdown:
yield top, dirs, nondirs
for name in dirs:
path = join(top, name)
if not islink(path):
for x in mywalk(path, topdown, onerror, ignore_list):
yield x
if not topdown:
yield top, dirs, nondirs
Istnieje możliwość modyfikowania drugi element wartości zwracanych os.walk
jest na miejscu:
[...] osoba wywołująca może zmodyfikować listę dirnames na miejscu (być może używając del lub przypisania plasterków), a walk() powróci tylko do podkatalogów, których imiona pozostaną w nazwiskach; może to zostać wykorzystane do wyczyszczenia wyszukiwania [...]
def fwalk(root, predicate):
for dirpath, dirnames, filenames in os.walk(root):
dirnames[:] = [d for d in dirnames if predicate(r, d)]
yield dirpath, dirnames, filenames
Teraz można po prostu ręcznie w orzecznika do podkatalogów:
>>> ignore_list = [...]
>>> list(fwalk("some/root", lambda r, d: d not in ignore_list))
Właściwie os.walk
może zrobić dokładnie to, co chcesz . Powiedzmy, że mam listę (być może zestaw) katalogów do zignorowania w ignore
. To powinno zadziałać:
def my_walk(top_dir, ignore):
for dirpath, dirnames, filenames in os.walk(top_dir):
dirnames[:] = [
dn for dn in dirnames
if os.path.join(dirpath, dn) not in ignore ]
yield dirpath, dirnames, filenames
Oto najlepsze i proste rozwiązanie.
def walk(ignores):
global ignore
path = os.getcwd()
for root, dirs, files in os.walk(path):
for ignore in ignores:
if(ignore in dirs):
dirs.remove(ignore)
print root
print dirs
print files
walk(['.git', '.svn'])
Pamiętaj, że jeśli usuniesz nazwę folderu z katalogu dirs, nie będzie on eksplorowany przez os.walk.
nadzieję, że pomoże
jakoś zapomniał o przydział slice, wziąłem wolności dodając, że do mojego kodu. –
Jest to oczekiwany sposób zrobienia tego, nawet tak jest napisane w dokumentacji os.path.walk(). – unwind
Nie, mam na myśli pełne przypisanie plastra jako sposobu na modyfikację całej listy, a nie fakt, że możesz to zmienić. –