I have functions to gather local filepaths like getExportFolder() or getSomeDataFilePath() etc…
What I have been doing is passing the result to a variable, and saving the variable as custom scene data.
But this lead to needing an updateLocalPaths() function,
and some other buggy things as the tools became more complex.
So I am beginning to think I should eschew variables in favor of functions at all times, for getting local filepaths.
Is this good practice?
You want to use the smallest possible number of functions you can to keep behavior the same across all your scripts. Have a casing and slash direction policy and stick to it. Have some kind of central repository of special folders or magic names and refer them as variables instead of hard coding.
from string import Template
import os
class Folders(object):
ROOT = Template('${ROOT}')
EXPORT = Template('${UL_PROJECT}/export')
IMAGE = Template('${UL_PROJECT}/renders/${current}')
TMP = Template('${user}/temp/maya')
class PathManager(object):
def __init__(self, **kwargs):
vars = {}
vars.update(os.environ)
vars.update(kwargs)
self.Vars = vars
def path(self, root, *segs):
root = root or Folders.ROOT # this lets you put None for the folder and use relative paths
path = root.safe_substitute(self.Vars)
args = [path] + list(segs)
return os.path.normpath(os.path.join(*args)).replace("\\", "/")
# I typically make a pathManager and use it repeatedly
pm = PathManager()
self.export_path = pm.path(folders.EXPORT, my_file_name)
write_image(pm.path(folders.IMAGE, 'path', 'to', 'image.jpg'))
relative_path = pm.path(none, "../folder_next_to_root")
The way it’s written you can override the externally set env vars with something like PathManager(ul_project =‘x:/alternate’). Ultimately you can only do so much to protect yourself against future reorganisations but a system where you call out the possible variables is a good start.
Yeah we kind of do a similar thing. During boot our pipeline binds a global Python “PROJECT” object which all our code now uses to extract project filepaths and variables, you switch project and the object is re-initialized for the new project. It means that all code just uses calls such as:
crysetp.PROJECT.build_path
The actual data is stored in a simple json config file per project. Having lots of getThisData() can get really messy and hard to manage when you’re dealing with multiple studios and projects.