Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having trouble understanding directory navigation with os.walk

I'm relatively new to python and I'm trying my hand at a weekend project. I want to navigate through my music directories and get the artist name of each music file and export that to a csv so that I can upgrade my music collection (a lot of it is from when I was younger and didn't care about quality).

Anyway, I'm trying to get the path of each music file in its respective directory, so I can pass it to id3 tag reading module to get the artist name.

Here is what I'm trying:

import os

def main():
    for subdir, dirs, files in os.walk(dir):
        for file in files:
            if file.endswith(".mp3") or file.endswith(".m4a"):
                print(os.path.abspath(file))

However, .abspath() doesn't do what I think it should. If I have a directory like this:

music
--1.mp3
--2.mp3
--folder
----a.mp3
----b.mp3
----c.mp3
----d.m4a
----e.m4a

and I run my code, I get this output:

C:\Users\User\Documents\python_music\1.mp3
C:\Users\User\Documents\python_music\2.mp3
C:\Users\User\Documents\python_music\a.mp3
C:\Users\User\Documents\python_music\b.mp3
C:\Users\User\Documents\python_music\c.mp3
C:\Users\User\Documents\python_music\d.m4a
C:\Users\User\Documents\python_music\e.m4a

I'm confused why it doesn't show the 5 files being inside of a folder. Aside from that, am I even going about this in the easiest or best way? Again, I'm new to python so any help is appreciated.

like image 532
swerly Avatar asked Dec 02 '25 00:12

swerly


1 Answers

You are passing just the filename to os.path.abspath(), which has no context but your current working directory.

Join the path with the subdir parameter:

print(os.path.join(subdir, file))

From the os.path.abspath() documentation:

On most platforms, this is equivalent to calling the function normpath() as follows: normpath(join(os.getcwd(), path)).

so if your current working directory is C:\Users\User\Documents\python_music all your files are joined relative to that.

But os.walk gives you the correct location to base filenames off instead; from the documentation:

For each directory in the tree rooted at directory top (including top itself), it yields a 3-tuple (dirpath, dirnames, filenames).

dirpath is a string, the path to the directory. [...] filenames is a list of the names of the non-directory files in dirpath. Note that the names in the lists contain no path components. To get a full path (which begins with top) to a file or directory in dirpath, do os.path.join(dirpath, name).

Emphasis mine.

like image 83
Martijn Pieters Avatar answered Dec 04 '25 14:12

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!