使用占位符定义命名目录结构

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用'*'替换丢失的字段)。在

转换为字符串

可以使用树中定义的名称访问路径:

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())

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
JAXB可以将ArrayList作为逗号分隔的值输出吗?   java使用bcel将一个内部类移动到另一个外部类   java无法识别Lucene MoreLikeThis中的错误   安卓如何在Frida中将动态类转换为json或java文件   java如何使用Struts2在blob类型的列中保存我的sql中的图像?   使用mavenreleaseplugin将java maven发布到nexus 3.0.1失败   java这是正确的方法吗?   Windows上的java Runner不工作   找不到java Hibernate+Spring xml映射   java如何访问WMI查询的数据(通过JNA)SAFEARRAY结果   java如何在本地导入库而不使用Maven中的Nexus?   java渐变本地项目依赖项   使用URLFetchService/URL Google appengine for java