使用占位符定义命名目录结构
path-tree的Python项目详细描述
路径树
命名路径层次结构
此包的目标是使您更容易在脚本和管道中定义和理解文件夹结构。当查看分散在脚本中的一系列os.path.join
命令时,我发现很难可视化文件结构,因此,您应该在顶部定义所有路径,然后填充占位符。在
安装
pip install path-tree
教程
快速启动
注意:我想更新这篇文章,使其更具说明性,不太冗长。问题是这个包可以做很多,但是很难脱离上下文简洁地显示出来。我不确定什么时候能有机会,但我会努力争取的!在
另外,我很抱歉没有API引用。我还没有完全把它加入到我的部署管道中!在
^{pr2}$老办法-让我的大脑悲伤
通常情况下,你定义路径的结果是这样的(除非我在做一些奇怪的/愚蠢的-lmk!!)。通常, 这些最终分散在您的项目中并获得较高的级别 你的路径层次图很难描绘。在
base_log_dir='./blah/logs'run_dir=os.path.join(base_log_dir,log_id)resources_dir=os.path.join(run_dir,'resources')...model_file=os.path.join(run_dir,'model.h5')model_spec=os.path.join(run_dir,'model_spec.pkl')...pump_file=os.path.join(resources_dir,'pump.pkl')...plot_dir=os.path.join(run_dir,'plots','epoch_{i_epoch:04d}')plot_file=os.path.join(plot_dir,'{plot_name}.png')
新方法!*大脑微笑*
相反,您可以在一个地方定义路径层次结构,并为每个树节点指定一个名称。在
importosimportpathtree# define the entire directory structure# the tree keys represent folder names.# the final non-dict key represents the name for# that directory node.## e.g.: {folder1: {folder2: name}}# paths.name => folder1/folder2## Notice the blank key under "plots". This takes advantage# of the fact that os.path.join('plots', '') == 'plots'.# So the name assigned to the blank string is naming the# directorybase_paths=pathtree.tree('./logs',{'{log_id}':{'model.h5':'model','model_spec.pkl':'model_spec','plots':{'epoch_{i_epoch:04d}':{'{plot_name}.png':'plot','':'plot_dir'# name for the directory}}}})# specify the log_id - specify returns a copy, update operates inplacepaths=base_paths.specify(log_id=12345)
基本概念
Paths
-使用pathtree.tree
定义的路径项集合。
从本质上讲,它是一个名为>;path的平面字典的包装器
以及提供给所有路径格式的数据字典。在Path
-单一路径。它扩展了os.PathLike
,因此可以在
需要路径对象(例如open(path).read()
)。它是pathlib.Path
对象和数据字典的包装器。
它提供了基本的路径操作(join('subdir')
,.up(2)
到2个父目录,.glob()
glob用'*'
替换丢失的字段)。在
转换为字符串
Paths
-使用pathtree.tree
定义的路径项集合。
从本质上讲,它是一个名为>;path的平面字典的包装器
以及提供给所有路径格式的数据字典。在Path
-单一路径。它扩展了os.PathLike
,因此可以在
需要路径对象(例如open(path).read()
)。它是pathlib.Path
对象和数据字典的包装器。
它提供了基本的路径操作(join('subdir')
,.up(2)
到2个父目录,.glob()
glob用'*'
替换丢失的字段)。在可以使用树中定义的名称访问路径:
assertstr(paths.model_spec)=='./logs/12345/model_spec.pkl'
Paths
对象(如上所定义)实际上只是name=>;pathtree.Path
对象的字典。这是字符串格式模式和数据字典的包装器。在
要将Path
转换为字符串,有几种方法可以得到您想要的结果。在
对于完全指定的字符串(意味着str.格式这三个方法都返回相同的结果:一个完全格式化的字符串。在
assertpaths.model.format()=='./logs/12345/model.h5'assertpaths.model.partial_format()=='./logs/12345/model.h5'assertpaths.model.maybe_format()=='./logs/12345/model.h5'
对于未指定的字符串(缺少数据键),返回值不同:
# str.format is missing a key and will throw an exceptiontry:paths.plot.format(plot_name='f1_score')assertFalseexceptKeyError:# missing i_epochassertTrue# str.format is missing a key so the missing key will be left inassert(paths.plot.partial_format(plot_name='f1_score')=='./logs/12345/plots/epoch_{i_epoch:04d}/f1_score.png')# str.format is missing a key so it will keep it as a Path object# with the updated key `plot_name`.# this retains the ability to use data updating functionality.assertisinstance(paths.plot.maybe_format(plot_name='f1_score'),pathtree.Path)
路径可转换为与partial_format
相同的字符串。也可以使用Path().path
访问未格式化的路径。在
assertstr(paths.plot)==paths.plot.partial_format()assertpaths.plot.path==the_unformatted_plot_path
pathtree.Path
子类os.PathLike
,意思是操作系统路径函数知道如何自动将其转换为路径。在
assertisinstance(paths.model,os.PathLike)assertos.path.join(paths.model)==paths.model.format()assertos.path.isfile(paths.model)
更新格式数据
您可以在沿途的不同点添加路径专用性。当需要根据某些循环或类似模式引用子目录时,这很有帮助。你可以用以下几种方法:
# across the entire directory object# update in placepaths.update(log_id=12345)# or create a copypaths2=paths.specify(log_id=23456)assertpaths.data['log_id']==12345andpaths2.data['log_id']=23456# reverse specify - remove a data keypaths2=paths2.unspecify('log_id')assert'log_id'notinpaths2.data# or for a single path# in placeplot_file=paths.plotplot_file.update(plot_name='f1_score')# create a copyplot_file=paths.plot.specify(plot_name='f1_score')assert'plot_name'notinpaths.dataassertplot_file.data['plot_name']=='f1_score'# reverse specify - remove a data keyplot_file=plot_file.unspecify('plot_name')assert'plot_name'notinplot_file.data
附加功能
你可以自动进行全局搜索。任何缺少的字段将用全局通配符(星号)填充。请注意,使用纯字符串格式将失败,因为如果您尝试插入'*'
(因为它是一个字符串),前导的零格式化程序(:04d
)将抛出一个错误。在
plot_file=paths.plot.specify(plot_name='f1_score')assert(plot_file.partial_format()=='./logs/12345/plots/epoch_{i_epoch:04d}/f1_score.png')assert(plot_file.glob_pattern=='./logs/12345/plots/epoch_*/f1_score.png')assert(plot_file.glob()==glob.glob('./logs/12345/plots/epoch_*/f1_score.png'))
有时还可以从格式化字符串中解析出数据。受到警告, 它可能并不总是正确工作,因为有时解析是不明确的。见https://github.com/r1chardj0n3s/parse#potential-gotchas
plot_file=paths.plot.specify(root='some/logs')assert(plot_file.partial_format()=='some/logs/12345/plots/epoch_{i_epoch:04d}/{plot_name}.png')expected={'root':'some/logs''log_id':'12345','i_epoch':'0002','plot_name':'f1_score.png',}plot_data=plot_file.parse('./logs/12345/plots/0002/f1_score.png')assertset(plot_data.items())==set(expected.items())
- 项目
标签: