Github link: shared.python.file
I often get mixed up with what file and folder operations are in os.path and in shutil. I also feel that the os module is not very readable. So, for the sake of readability, I like to add a few functions that help out with file and folder operations.
One example of how unreadable os.path can be is getting a file name.
file_name = os.path.dirname(r"C:\path\fileName.ext")
Pretty horrible, no? I mean the function is called dirname as if we were looking a the name of a directory!
With name(), we can get the name of a file in a much more readable way. And, since we bothered with this, we can get the name of the file without the extension like so:
import shared.python.file as pyfile file_name = pyfile.name(r"C:\path\fileName.ext", include_ext=False)
This function will return all files within a folder. You can obviously do this in line, but its really nice to have it as a one line function.
To make this function, I started with the line that gets me the list of files:
for (dirpath, dirnames, filenames) in os.walk(path): files.extend([os.path.join(dirpath, x) for x in filenames])
That gives me a list of all the files in all the folders in the given path. That’s useful unless you only want the files in the path, and not in all the sub-folders. So we can add an if for that case:
for (dirpath, dirnames, filenames) in os.walk(path): files.extend([os.path.join(dirpath, x) for x in filenames]) if not recursive: break
At this point we now have the correct list of files. This trick I learned from a friend at work. He uses the break command in interesting ways. In this case, it breaks the os.walk() command right after the first loop. This means that it skips all the sub-folders, leaving the list with the files in the base folder only.
Lastly, filter files to the given extensions. I like to feed the extensions as a list. This way, you can assemble your extensions in a loop. So assume the extensions are [“ma”, “mb”]:
for (dirpath, dirnames, filenames) in os.walk(path): files.extend([os.path.join(dirpath, x) for x in filenames]) if not recursive: break if extension: filtered = list() extenstions = pyutils.make_list(extension) for e in extenstions: e = "." + e.replace(".", "") for i, file_name in enumerate(files): add = False for e in extenstions: if file_name.endswith(e): add = True break if add: filtered.append(file_name) files = filtered
The first loop makes sure that all extensions start with a “.”.
The second loop adds the files to filtered only if they have the right extension.
And this is how the function is used:
import shared.python.file as pyfile maya_files = pyfile.list_files(r"C:\path", extension=["ma","mb"], recursive=True)
For the complete code, please refer to the function in git (shared.python.file)
If you have any doubts or questions about any of the functions or the module itself, please add it to the comments. I’ll be happy to add any clarification to this post or to change the module itself (where it makes sense).