如何使用 pytables 取消引用外部链接列表?
How to de-reference a list of external links using pytables?
我使用 pytables 创建了从一个 hdf5 文件到另一个文件的外部 links。我的问题是如何在循环中取消引用它?
例如:
让我们假设 file_name = "collection.h5"
,存储外部 link 的地方
我在根节点下创建了外部 links,当我遍历根下的节点时,我得到以下输出:
/link1(外部链接)-> /files/data1.h5:/weights/Image
/link2(外部链接)-> /files/data2.h5:/weights/Image
等等,
我知道要取消对 link 的引用,可以这样做,使用以下方式的自然命名:
f = open_file('collection.h5',mode='r')
plink1 = f.root.link1()
plink2 = f.root.link2()
但我想在 for 循环中执行此操作,对此有任何帮助吗?
您可以使用iter_nodes()
或walk_nodes()
; walk_nodes
是递归的,iter_nodes
不是。 iter_nodes()
的示例在我对此 SO 主题的回答中进行了解释:
我发现您不能使用 get_node()
来引用外部链接。您需要以不同的方式引用。
这是一个简单的示例,它从本地文件夹中的 HDF5 文件列表创建 collection.h5
,然后在 for
循环中使用 iter_nodes()
。请注意,这是一个非常基本的示例。它不检查节点的对象类型(Group 或 Leaf 或 ExternalLink)。它假定根级别的每个 Node 都是一个 ExternalLink,并从该节点创建一个文件对象。还有其他 PyTables 方法和属性可以检查这些情况。有关更强大(复杂)的方法,请参阅下面的详细答案。
import tables as tb
import glob
h5f = tb.open_file('collection.h5',mode='w')
link_cnt = 0
for h5name in glob.glob('./SO*.h5'):
link_cnt += 1
h5f.create_external_link('/', 'link'+str(link_cnt), h5name+':/')
h5f.close()
h5f = tb.open_file('collection.h5',mode='r')
for link_node in h5f.iter_nodes('/') :
print("``%s`` is an external link to: ``%s``" % (link_node, link_node.target))
plink = link_node(mode='r') # returns a FILE object
h5f.close()
这是一个更完整(稳健且复杂)的答案,用于处理在任何组级别都有 ExternalLink 时的一般情况。它与上面类似,但使用 walk_nodes()
因为它在根级别有 3 个组,并且包括对 ExternalLink 类型的测试(参见 isinstance()
)。此外,它还展示了如何使用 _v_children
属性来获取节点字典。 (我无法 list_nodes()
使用外部链接。)
import tables as tb
import glob
h5f = tb.open_file('collection.h5',mode='w')
link_cnt = 0
pre_list = ['SO_53', 'SO_54', 'SO_55']
for h5f_pre in pre_list :
h5f_pre_grp = h5f.create_group('/', h5f_pre)
for h5name in glob.glob('./'+h5f_pre+'*.h5'):
link_cnt += 1
h5f.create_external_link(h5f_pre_grp, 'link_'+'%02d'%(link_cnt), h5name+':/')
h5f.close()
h5f = tb.open_file('collection.h5',mode='r')
for link_node in h5f.walk_nodes('/') :
if isinstance(link_node, tb.link.ExternalLink) :
print('\nFor Node %s:' % (link_node._v_pathname) )
print("``%s`` is an external link to: ``%s``" % (link_node, link_node.target))
plink = link_node(mode='r') # this returns a file object for the linked file
linked_nodes = plink._v_children
print (linked_nodes)
h5f.close()
我使用 pytables 创建了从一个 hdf5 文件到另一个文件的外部 links。我的问题是如何在循环中取消引用它?
例如:
让我们假设 file_name = "collection.h5"
,存储外部 link 的地方
我在根节点下创建了外部 links,当我遍历根下的节点时,我得到以下输出:
/link1(外部链接)-> /files/data1.h5:/weights/Image
/link2(外部链接)-> /files/data2.h5:/weights/Image
等等,
我知道要取消对 link 的引用,可以这样做,使用以下方式的自然命名:
f = open_file('collection.h5',mode='r')
plink1 = f.root.link1()
plink2 = f.root.link2()
但我想在 for 循环中执行此操作,对此有任何帮助吗?
您可以使用iter_nodes()
或walk_nodes()
; walk_nodes
是递归的,iter_nodes
不是。 iter_nodes()
的示例在我对此 SO 主题的回答中进行了解释:
get_node()
来引用外部链接。您需要以不同的方式引用。
这是一个简单的示例,它从本地文件夹中的 HDF5 文件列表创建 collection.h5
,然后在 for
循环中使用 iter_nodes()
。请注意,这是一个非常基本的示例。它不检查节点的对象类型(Group 或 Leaf 或 ExternalLink)。它假定根级别的每个 Node 都是一个 ExternalLink,并从该节点创建一个文件对象。还有其他 PyTables 方法和属性可以检查这些情况。有关更强大(复杂)的方法,请参阅下面的详细答案。
import tables as tb
import glob
h5f = tb.open_file('collection.h5',mode='w')
link_cnt = 0
for h5name in glob.glob('./SO*.h5'):
link_cnt += 1
h5f.create_external_link('/', 'link'+str(link_cnt), h5name+':/')
h5f.close()
h5f = tb.open_file('collection.h5',mode='r')
for link_node in h5f.iter_nodes('/') :
print("``%s`` is an external link to: ``%s``" % (link_node, link_node.target))
plink = link_node(mode='r') # returns a FILE object
h5f.close()
这是一个更完整(稳健且复杂)的答案,用于处理在任何组级别都有 ExternalLink 时的一般情况。它与上面类似,但使用 walk_nodes()
因为它在根级别有 3 个组,并且包括对 ExternalLink 类型的测试(参见 isinstance()
)。此外,它还展示了如何使用 _v_children
属性来获取节点字典。 (我无法 list_nodes()
使用外部链接。)
import tables as tb
import glob
h5f = tb.open_file('collection.h5',mode='w')
link_cnt = 0
pre_list = ['SO_53', 'SO_54', 'SO_55']
for h5f_pre in pre_list :
h5f_pre_grp = h5f.create_group('/', h5f_pre)
for h5name in glob.glob('./'+h5f_pre+'*.h5'):
link_cnt += 1
h5f.create_external_link(h5f_pre_grp, 'link_'+'%02d'%(link_cnt), h5name+':/')
h5f.close()
h5f = tb.open_file('collection.h5',mode='r')
for link_node in h5f.walk_nodes('/') :
if isinstance(link_node, tb.link.ExternalLink) :
print('\nFor Node %s:' % (link_node._v_pathname) )
print("``%s`` is an external link to: ``%s``" % (link_node, link_node.target))
plink = link_node(mode='r') # this returns a file object for the linked file
linked_nodes = plink._v_children
print (linked_nodes)
h5f.close()