Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have this function to prevent FileExistsError . It creates a folder, but if there is another folder with the same name, it will add an sequential number to the name of that folder.

import os
def create_folder(folder_name):
      path = '/home/k/Desktop/' + folder_name
      folder_number = 1
      if os.path.exists(path):
            while path == os.path.exists(path):
                  folder_number += 1
            path = '/home/k/Desktop/' + folder_name + ' ({})'.format(folder_number)
            os.makedirs(path)
      else:
            os.makedirs(path)

I am able to make the folder, and if i create another folder with the same name, i will set the name to myfoldername(1), but if a create it again it will raise FileExistsError:

FileExistsError: [Errno 17] File exists: '/home/k/Desktop/test (1)'

I think the error is in the while loop but i don't know how to fix it.

The assignment of a new path name with the incremented number should be inside the while loop so that path can be updated, and the condition for the while loop needs only the returning Boolean value os.path.exists method:

while os.path.exists(path):
    folder_number += 1
    path = '/home/k/Desktop/' + folder_name + ' ({})'.format(folder_number)

Your code has two issues. The first is that the condition of your while loop doesn't make any sense. You're doing path == os.path.exists(path), but the function call returns either True or False, neither of which will ever equal the path string. You should just use os.path.exists(path) as the condition.

The second issue is that you're not updating path inside the loop. You need to move the line that updates it to account for the incremented folder number so that you don't keep checking the same path over and over forever.

Here's how I'd rewrite that code:

def create_folder(folder_name):
      path = '/home/k/Desktop/' + folder_name
      folder_number = 1
      while path == os.path.exists(path):
          path = '/home/k/Desktop/{} ({})'.format(folder_name, folder_number)
          folder_number += 1
      os.makedirs(path)
      return path

I made a few other changes, beyond the ones causing your current error. I got rid of the if statement which was completely unnecessary, since the while loop will not run it's body if the condition is falsey on the first go. That means the os.makedirs call is unconditional. In addition to indenting the path-updating line, I also rewrote it to just use one formatting operation, rather than also doing some concatenations. I also reordered it relative to the increment step, so that you'll start numbering at 1, rather than 2. And finally, I added a return statement to the end, as you're probably going to want to use that folder you just created, and without returning the final path, the calling code will not know what number we had to increment up to.

The error you are getting is a result of folder_number being set to 1 outside of the exists check. Every time it attempts to prevent the FileExistsError it tries to solve the problem by creating the folder name with a " (1)" appended to it. If that already exists, then you get the FileExistsError anyway.

As with many things in python, there are many different ways to fix this issue. The easiest way that I could make it work while still resembling your function's logic would be to combine your while loop with your os.path.exists check, so that while the check for the path already existing return True, the while loop increments the number in the parentheses. After the exist check returns False, it will perform the create folder operation. This is an example of the Look Before You Leap (LBYL) principle:

import os
def create_folder(folder_name):
    path = '/home/k/Desktop/' + folder_name
    folder_number = 1
    while os.path.exists(path):
        folder_number += 1
        path = '/home/k/Desktop/' + folder_name + ' ({})'.format(folder_number)
    os.makedirs(path) 

There is a also a principle in python that is commonly implemented that could help you out here too called Easier to Ask Forgiveness than Permission (EAFP). Basically, you could wrap the os.makedirs(path) operation inside of try.. except statement.

That would look like this:

import os
def create_folder(folder_name):
   path = '/home/k/Desktop/' + folder_name
   folder_number = 0
   while os.path.exists(path):
           os.makedirs(path)
       except FileExistsError:
           folder_number += 1
           path = '{} ({})'.format(path, folder_number)
           continue

Here the path is modified if a FileExistsError occurs and then the continue statement tells the while loop to "continue" instead of exiting.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.