-1

I want to change files with extension ".py" to ".txt" for all files within folders and subfolders. What I did with my code is :

def py_to_txt(directory):
    for foldername, subfolders, filenames in os.walk(dire):
        print(filenames)
        for f in filenames :
            if f.endswith('.py'):
                base = os.path.splitext(f)[0]
                os.rename(f, base + '.txt')

and this code only changes the first file extension in the parent directory and then throws the following error :

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-69-ed0d85ebad81> in <module>
----> 1 py_to_txt(dire)

<ipython-input-68-1efd842876ed> in py_to_txt(directory)
      5             if f.endswith('.py'):
      6                 base = os.path.splitext(f)[0]
----> 7                 os.rename(f, base + '.txt')
      8 

FileNotFoundError: [Errno 2] No such file or directory: 'file2.py' -> 'file2.txt'

What is the right way of doing it ?

Akash Dubey
  • 304
  • 1
  • 11

1 Answers1

1

One thing I might note would be that you're missing the addition of foldername to each filename f -- without that, you're asking it to delete files from your current working directory, not from their actual location.

Try:

def py_to_txt(directory):
    for foldername, subfolders, filenames in os.walk(directory):
        print(filenames)
        for f in filenames :
            if f.endswith('.py'):
                base = os.path.splitext(f)[0]
                os.rename(os.path.join(foldername, f), 

os.path.join(foldername, base + '.txt'))


The issue here is that when you go to use os.walk(), it returns three items:

  1. The directory it's currently traversing (we'll call it base)
  2. The directories within base
  3. The files within base

So if we have a folder:

py/
  1.py
  2.py

Running os.walk('py/') will yield:

('py/', (), ('1.py', '2.py'))

Note that those last items don't actually contain their own full path -- they're the last part of the path, the file's name and extension. As a result, if you want the absolute path to an object, you have to join the base to the filename, like this:

for base, dirs, files in os.walk(directory):
    for filename in files:
        full_path = os.path.join(base, filename)
        print(filename, 'is different than', full_path)
inim
  • 146
  • 3
  • 1
    Not working. Raises the following error `FileNotFoundError: [Errno 2] No such file or directory: 'file2.py' -> '/home/akash/Desktop/testfolder/testfolder1/file2.txt'` – Akash Dubey Dec 19 '19 at 18:12
  • @AkashDubey -- whoops, missed a reference to `f` in the rename call. Try now. – inim Dec 19 '19 at 18:14
  • works like charm. Thank you very much. One question though, what was I doing wrong ? – Akash Dubey Dec 19 '19 at 18:17
  • What if I want to change every file withing folders and subfolder to a same extension but want the original ext as file_oldExtension.newExtension and convert them back to the original name. – Akash Dubey Dec 20 '19 at 10:27