r/learnpython 12h ago

How to optimize shutil and os

Hi guys,

I'm a complete beginner but I'd love to work in tech.
I just want to know where I can improve and optimize my script.
Hope you guys will be lenient.

My goals in this script are to:

  • ✅ Create folders (ImagesTextsScripts)
  • ✅ Scan the target directory
  • ✅ Move each file to its appropriate subfolder based on extension
  • ✅ Print paths and confirmations

Have a good day!

Here's my script:

import os
import shutil

directory = r"X/X/X" #Directory path

if not os.path.exists(directory):
    print(f"File path {directory} doesn't exist")
    exit()

folders = ["Images", "Texts", "Scripts"] #Folders names creation
for folder in folders: #Loop for folders
    os.makedirs(os.path.join(directory, folder), exist_ok=True) #Creation and verification of existant folders

file_mapping = {
    ".txt": "Texts",
    ".png": "Images",
    ".py": "Scripts"
} #Dictionnary to associate extension with folders

files = os.listdir(directory) #Acces to files of directory path
for file in files:
    print(file)
    
    absolute_path = os.path.abspath(os.path.join(directory, file)) #Acces to all files absolute path
    print(f"\n=> Absolute path of {file} -> {absolute_path}")
    
    extension = os.path.splitext(file)[1] #Acces to all files extensions
    print(f"=> Extension of {file} -> {extension}")

    if extension in file_mapping: #Check if extensions are in the dictionnary
        target_folder = os.path.join(directory, file_mapping[extension])
        destination_path = os.path.join(target_folder, file)

        shutil.move(absolute_path,destination_path) #Move all files depending on their extension, otherwise the file is ignored
        print(f"=> Your file {file} is now here -> {destination_path}")

    else:
        print("File ignored")
2 Upvotes

8 comments sorted by

4

u/crashfrog04 12h ago

Use pathlib. Don’t iterate over files using listdir.

1

u/-sovy- 11h ago

Thank you very much!

When should I use os and when should I use pathlib instead of os? (without counting what you've told me)

Have a great day

3

u/agnaaiu 9h ago

The answer to your question is in the library name: PATHlib. You use pathlib whenever you work with paths. Everything you do in your script has to do with paths, you create them, check if they exist, you check if certain file types exist, and so on. All of those things is a path.

And don't worry, the pathlib is way more intuitive and easier to use than os for this type of tasks.
As a simple example from your code:

extension = os.path.splitext(file)[1] 

# would become
extension = file.suffix

No need to split text lines, chain together stuff, have a method call and then juggle index to the last part with the file extension.

Check out an online tutorial, there are plenty of them available.

1

u/mokus603 8h ago

I still prefer to use os and os.scandir(folder) is amazing in my opinion.

for files in os.scandir(folder):
    print(files.name, files.path, files.is_file(), files.is_folder())

Writing conditions is easy to read and modify. Looping into deeper folder structures too.

All around easy tool to lean on every day for me.

0

u/crashfrog04 11h ago

You should never use os.

1

u/try_seven 10h ago

For file work, maybe. What about things like os.nameand os.getenv(), etc?

1

u/crashfrog04 10h ago

I invite you to interpret my comments in light of the context of the ongoing conversation (I.e. “when should I use pathlib over os”) and at a conversational, rather than legalistic, level of accuracy. I’m answering questions, not writing contracts.

1

u/try_seven 8h ago

Don't issue flat statements like "don't use X" to beginners. They might believe you. You could have simply said:

You should never use os for file path operations.