简体   繁体   中英

how to get file path in list?

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.

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, ie 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()]

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)

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')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM