I'm trying to learn python.
I would like to have a list of all files in all subdirectories and then pick one random file and open it (all files are different image types).
At the moment, I get:
Traceback (most recent call last):
File "c:\Users\xxx\OneDrive\Desktop\pythonProject\test.py", line 20, in <module>
os.startfile(d)
FileNotFoundError: [WinError 2] Das System kann die angegebene Datei nicht finden: (file can not be found)
I guess it is because I only get the NAME of the file and not the path?
How could I list all file paths and then pick one at random?
Full code below:
import random
import os
from os import walk
# folder path
dir_path = "M:/01_Bilder/01_Shootings"
# list to store files name
AllFiles = []
for (dir_path, dir_names, file_names) in walk(dir_path):
AllFiles.extend(file_names)
print(AllFiles)
d=random.choice(AllFiles)
print("file is " d)
os.startfile(d)
I am new to python and got here with a tutorial, but I do not yet fully understand how python works. Please be patient.
CodePudding user response:
The third item that os.walk
gives you only the names of files, not their entire path. os.startfile
then searches for the filename in the directory you're running your script from.
You either have to also combine the path of the containing folder, the first item that os.walk
gives you, with the filename:
# NOTE: To avoid name conflicts, I'd recomment changing the name
# of this variable to not crash into your initial path.
# Therefore, dir_path -> current_dir_path
for (current_dir_path, dir_names, file_names) in walk(dir_path):
for file_name in file_names:
AllFiles.append(os.path.join(current_dir_path, file_name))
Or you can use a tool that does that for you, i.e. pathlib
, which gives you Path
-objects with absolute paths included.
import pathlib
...
AllFiles = [file for file in pathlib.Path(dir_path).rglob("*") if file.is_file()]
CodePudding user response:
To make your code work I changed the way of adding the files to the list 'ALLFiles':
import random
import os
from os import walk
# folder path
dir_path = "folder"
# list to store files name
AllFiles = []
for (dir_path, dir_names, file_names) in walk(dir_path):
for file in file_names:
AllFiles.append(dir_path os.sep file)
print(AllFiles)
d=random.choice(AllFiles)
print("file is " d)
os.startfile(d)
CodePudding user response:
I would highly recommend using pathlib
. It is a more modern interface for dealing with files that better deals with filesystem objects, including paths, filenames, permissions, etc..
>>> import random
>>> from pathlib import Path
>>> p = Path('/tmp/photos')
>>> files = [x for x in p.glob('**/*') if x.is_file()]
>>> random_file = random.choice(files)
>>> print(random_file)
/tmp/photos/photo_queue/KCCY2238.JPEG
It gives you easy ways to deal with lots of things you would want to do with files:
>>> file = files[0]
>>> file.name
'GYEP0506.JPG'
>>> file.stem
'GYEP0506'
>>> file.suffix
'.JPG'
>>> file.parent
PosixPath('/tmp/photos/photo_queue')
>>> file.parent.name
'photo_queue'
>>> file.parts
('/', 'tmp', 'photos', 'photo_queue', 'GYEP0506.JPG')
>>> file.exists()
True
>>> file.is_absolute()
True
>>> file.owner()
'daniel'
>>> file.with_stem('something_else')
PosixPath('/tmp/photos/photo_queue/something_else.JPG')