Begrijp ik os.walk goed?

De lus voor root, dir, file in os.walk(startdir) werkt via deze stappen?

for root in os.walk(startdir) 
    for dir in root 
        for files in dir
  1. hoofdmap van startmap ophalen: C:\dir1\dir2\startdir

  2. verkrijg mappen in C:\dir1\dir2\startdir en retourneer de lijst met mappen “dirlist”

  3. haal bestanden in het eerste dirlist-item en retourneer de lijst met bestanden “filelist” als het eerste item van een lijst met bestandslijsten.

  4. ga naar het tweede item in dirlist en retourneer de lijst met bestanden in deze map “filelist2” als het tweede item van een lijst met bestandslijsten. enz.

  5. ga naar de volgende root in de mappenboom en begin bij 2. etc.

Toch? Of krijgt het eerst alle wortels, dan alle mappen als tweede en alle bestanden als derde?


Antwoord 1, autoriteit 100%

os.walk retourneert een generator, die een tupel van waarden creëert (current_path, directories in current_path, bestanden in current_path).

Elke keer dat de generator wordt aangeroepen, zal deze elke directory recursief volgen totdat er geen subdirectories meer beschikbaar zijn uit de oorspronkelijke directory die walk werd aangeroepen.

Als zodanig,

os.walk('C:\dir1\dir2\startdir').next()[0] # returns 'C:\dir1\dir2\startdir'
os.walk('C:\dir1\dir2\startdir').next()[1] # returns all the dirs in 'C:\dir1\dir2\startdir'
os.walk('C:\dir1\dir2\startdir').next()[2] # returns all the files in 'C:\dir1\dir2\startdir'

Dus

import os.path
....
for path, directories, files in os.walk('C:\dir1\dir2\startdir'):
     if file in files:
          print('found %s' % os.path.join(path, file))

of dit

def search_file(directory = None, file = None):
    assert os.path.isdir(directory)
    for cur_path, directories, files in os.walk(directory):
        if file in files:
            return os.path.join(directory, cur_path, file)
    return None

of als u naar een bestand wilt zoeken, kunt u dit doen:

import os
def search_file(directory = None, file = None):
    assert os.path.isdir(directory)
    current_path, directories, files = os.walk(directory).next()
    if file in files:
        return os.path.join(directory, file)
    elif directories == '':
        return None
    else:
        for new_directory in directories:
            result = search_file(directory = os.path.join(directory, new_directory), file = file)
            if result:
                return result
        return None

Antwoord 2, autoriteit 52%

Minimaal uitvoerbaar voorbeeld

Zo leer ik graag dingen:

mkdir root
cd root
mkdir \
  d0 \
  d1 \
  d0/d0_d1
touch \
  f0 \
  d0/d0_f0 \
  d0/d0_f1 \
  d0/d0_d1/d0_d1_f0
tree

Uitvoer:

.
+-- d0
¦   +-- d0_d1
¦   ¦   L-- d0_d1_f0
¦   +-- d0_f0
¦   L-- d0_f1
+-- d1
L-- f0

main.py

#!/usr/bin/env python3
import os
for path, dirnames, filenames in os.walk('root'):
    print('{} {} {}'.format(repr(path), repr(dirnames), repr(filenames)))

Uitvoer:

'root' ['d0', 'd1'] ['f0']
'root/d0' ['d0_d1'] ['d0_f0', 'd0_f1']
'root/d0/d0_d1' [] ['d0_d1_f0']
'root/d1' [] []

Dit maakt alles duidelijk:

  • path is de hoofdmap van elke stap
  • dirnames is een lijst met directory-basisnamen in elk path
  • filenames is een lijst met bestandsbasisnamen in elk path

Getest op Ubuntu 16.04, Python 3.5.2.

Het wijzigen van dirnames verandert de boomrecursie

Dit is eigenlijk het enige andere waar u rekening mee moet houden.

Als u bijvoorbeeld de volgende bewerkingen uitvoert op dirnames, heeft dit invloed op de verplaatsing:

Loop bestand of map

Als de invoer om door te bladeren een bestand of map is, kunt u dit als volgt afhandelen:

#!/usr/bin/env python3
import os
import sys
def walk_file_or_dir(root):
    if os.path.isfile(root):
        dirname, basename = os.path.split(root)
        yield dirname, [], [basename]
    else:
        for path, dirnames, filenames in os.walk(root):
            yield path, dirnames, filenames
for path, dirnames, filenames in walk_file_or_dir(sys.argv[1]):
    print(path, dirnames, filenames)

Antwoord 3, autoriteit 13%

In eenvoudige bewoordingen zal os.walk() een reeks pad, mappen en bestanden genereren die aanwezig zijn in het gegeven pad en zal doorgaan met het doorlopen van de submappen.

import os.path
path=input(" enter the path\n")
for path,subdir,files in os.walk(path):
   for name in subdir:
       print os.path.join(path,name) # will print path of directories
   for name in files:    
       print os.path.join(path,name) # will print path of files

dit genereert paden van alle submappen, bestanden en bestanden in submappen


Antwoord 4, autoriteit 5%

Hier is een kort voorbeeld van hoe os.walk () werkt samen met enige uitleg met behulp van een paar os-functies.

Merk eerst op dat os.walk() retourneert drie items, de hoofdmap, een lijst met mappen (dirs) direct onder de huidige hoofdmap en een lijst met bestanden die in die mappen zijn gevonden. De documentatie geeft je meer informatie.

dirs zal een lijst met mappen net onder root bevatten, en bestanden zullen een lijst bevatten van alle bestanden die in die mappen zijn gevonden. In de volgende iteratie zal elke directory van die in de vorige dirs-lijst om de beurt de rol van root op zich nemen en het zoeken zal vanaf daar verder gaan, alleen een niveau lager nadat het huidige niveau is gezocht.

Een codevoorbeeld: dit zoekt, telt en drukt de namen van .jpg– en .gif-bestanden af ​​onder de opgegeven zoekdirectory (uw root). Het maakt ook gebruik van het os.path. splitext() functie om de basis van het bestand te scheiden van de extensie en de os.path.join() functie om u de volledige naam te geven, inclusief het pad van de gevonden afbeeldingsbestanden.

import os
searchdir = r'C:\your_root_dir'  # your search starts in this directory (your root) 
count = 0
for root, dirs, files in os.walk(searchdir):
    for name in files:
        (base, ext) = os.path.splitext(name) # split base and extension
        if ext in ('.jpg', '.gif'):          # check the extension
            count += 1
            full_name = os.path.join(root, name) # create full path
            print(full_name)
print('\ntotal number of .jpg and .gif files found: %d' % count)

Antwoord 5, autoriteit 2%

os.walk werkt een beetje anders dan hierboven. Kortom, het retourneert tupels van (pad, mappen, bestanden). Probeer het volgende om dit te zien:

import pprint
import os
pp=pprint.PrettyPrinter(indent=4)
for dir_tuple in os.walk("/root"):
    pp.pprint(dir_tuple)

…je zult zien dat elke iteratie van de lus een mapnaam zal afdrukken, een lijst met de namen van alle mappen onmiddellijk in die map, en een andere lijst van alle bestanden in die map. os.walk zal dan elke map in de lijst met submappen invoeren en hetzelfde doen, totdat alle submappen van de oorspronkelijke root zijn doorlopen. Het kan helpen om iets over recursie te leren om te begrijpen hoe dit werkt.


Antwoord 6

Mijn antwoord is heel eenvoudig en duidelijk. Ik ben zelf een beginner en vond mijn antwoorden op internet (zie in het bijzonder de goede documentatie op docs.python.org) en wat testcode proberen, zoals deze:

for root, dirs, files in os.walk(startdir)
    print ("__________________")
    print (root)
    for file in files:
        print ("---",file)

Hiermee wordt de directorystructuur afgedrukt, waarbij elke map de startmap en de meegeleverde submappen worden voorafgegaan door een regel en gevolgd door de bestanden die erin staan.

Ik denk dat je twee dingen in gedachten moet houden:

(1) os.walk genereert een 3-tuple (een triple) <root,dirs,bestandsnamen> waar

  • root is een tekenreeks die de naam van de hoofdmap bevat;

  • dirs is een lijst met strings: de directorynamen die direct in root zitten, dat wil zeggen op het eerste niveau, zonder dat de submappen mogelijk zijn opgenomen in
    hen;

  • bestandsnamen is een lijst van strings: de bestandsnamen die rechtstreeks in root zitten.

(2) een for-lus zoals

for root, subdirs, files in os.walk(YourStartDir)

loopt door de hoofdmap en al zijn submappen. Er is geen stap nodig voor elk bestand; het scant gewoon de mappenboom en bij elke stap (voor elke map in de boom) vult het de lijst met de bestandsnamen die erin staan ​​en de lijst met submappen die er direct in staan. Als je n mappen hebt (inclusief root en zijn submappen), loopt de for-lus n keer, dwz het kost n stappen. U kunt een kort stukje testcode schrijven om dit te controleren, bijvoorbeeld met behulp van een teller.
Bij elke stap genereert het een 3-tupel: een string plus twee (mogelijk lege) lijsten met strings.
In dit voorbeeld heten de elementen van de 3-tuple: “root”, “subdirs”, “files”, maar deze namen zijn aan jou; als uw code is

for a, b, c in os.walk(startdir)

de elementen van de 3-tupel worden “a”, “b”, “c” genoemd.

Laten we teruggaan naar de testcode:

for root, dirs, files in os.walk(startdir)
    print ("__________________")
    print (root)
    for file in files:
        print ("---",file)

Eerste lus: root is de map die je hebt opgegeven in de invoer (het startpad, de startmap: een string), dirs is de lijst met de namen van de opgenomen subdirectories (maar niet van de namen van de daarin opgenomen mappen), is bestanden de lijst met de opgenomen bestanden. In de testcode gebruiken we de lijst “dirs”.

Tweede lus: root is nu de eerste submap, dirs is een lijst van de submappen die er in zijn, bestanden is een lijst van de bestanden die erin zijn opgenomen.

enzovoort, totdat u de laatste submap in de boom bereikt.

Er zijn drie optionele argumenten voor os.walk: je kunt veel informatie over hen en hun gebruik op internet vinden, maar ik denk dat je vraag over de basis van os.walk gaat.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes