Python: 始终导入目录中的最后修订版
Python: always import the last revision in the directory
假设我们有以下数据库结构,数据存储在 python 个文件中,准备导入:
data_base/
foo_data/
rev_1.py
rev_2.py
bar_data/
rev_1.py
rev_2.py
rev_3.py
在我的主脚本中,我想导入文件夹中可用数据的最后 修订版。例如,而不是这样做:
from data_base.foo_data.rev_2 import foofoo
from data_base.bar_data.rev_3 import barbar
我要调用一个方法:
import_from_db(path='data_base.foo_data', attr='foofoo', rev='last')
import_from_db(path='data_base.bar_data', attr='barbar', rev='last')
我可以采用数据库的相对路径并使用 glob.glob
搜索最新修订版,但为此,我应该知道 data_base
文件夹的路径,这会使事情变得复杂(假设 data_base
的父文件夹在 sys.path 中,所以 from data_base.*** import
可以工作)
是否有一种有效的方法可以检索仅知道其中一部分的完整路径 (data_base.foo_data
)?其他想法?
我觉得安装最后一个版本比较好
但继续您的流程,您可以在模块上使用 getattr
:
from data_base import foo_data
i = 0
while True:
try:
your_module = getattr(foo_data, f'rev_{i}')
except AttributeError:
break
i += 1
# Now your_module is the latest rev
@JohnDoriaN 的想法使我找到了一个非常简单的解决方案:
import os, glob
def import_from_db(import_path, attr, rev_id=None):
"""
"""
# Get all the modules/folders names
dir_list = import_path.split('.')
# Import the last module
exec(f"from {'.'.join(dir_list[:-1])} import {dir_list[-1]}")
db_parent = locals()[dir_list[-1]]
# Get an absolute path to corresponding to the db_parent folder
abs_path = db_parent.__path__._path[0]
rev_path = os.path.join(abs_path, 'rev_*.py')
rev_names = [os.path.basename(x) for x in glob.glob(rev_path)]
if rev_id is None:
revision = rev_names[-1]
else:
revision = rev_names[rev_id]
revision = revision.split('.')[0]
# import attribute
exec(f'from {import_path}.{revision} import {attr}', globals())
一些解释:
- 显然(我不知道这一点),我们可以将文件夹作为模块导入;这个模块有一个
__path__
属性(使用内置的 dir
方法找到)。
glob.glob
允许我们使用正则表达式来搜索目录中文件所需的模式。
- 使用不带参数的
exec
将仅在本地命名空间(方法的命名空间)中导入,因此不会污染全局命名空间。
- 使用
exec
和 globals()
允许我们在全局命名空间中导入。
假设我们有以下数据库结构,数据存储在 python 个文件中,准备导入:
data_base/
foo_data/
rev_1.py
rev_2.py
bar_data/
rev_1.py
rev_2.py
rev_3.py
在我的主脚本中,我想导入文件夹中可用数据的最后 修订版。例如,而不是这样做:
from data_base.foo_data.rev_2 import foofoo
from data_base.bar_data.rev_3 import barbar
我要调用一个方法:
import_from_db(path='data_base.foo_data', attr='foofoo', rev='last')
import_from_db(path='data_base.bar_data', attr='barbar', rev='last')
我可以采用数据库的相对路径并使用 glob.glob
搜索最新修订版,但为此,我应该知道 data_base
文件夹的路径,这会使事情变得复杂(假设 data_base
的父文件夹在 sys.path 中,所以 from data_base.*** import
可以工作)
是否有一种有效的方法可以检索仅知道其中一部分的完整路径 (data_base.foo_data
)?其他想法?
我觉得安装最后一个版本比较好
但继续您的流程,您可以在模块上使用 getattr
:
from data_base import foo_data
i = 0
while True:
try:
your_module = getattr(foo_data, f'rev_{i}')
except AttributeError:
break
i += 1
# Now your_module is the latest rev
@JohnDoriaN 的想法使我找到了一个非常简单的解决方案:
import os, glob
def import_from_db(import_path, attr, rev_id=None):
"""
"""
# Get all the modules/folders names
dir_list = import_path.split('.')
# Import the last module
exec(f"from {'.'.join(dir_list[:-1])} import {dir_list[-1]}")
db_parent = locals()[dir_list[-1]]
# Get an absolute path to corresponding to the db_parent folder
abs_path = db_parent.__path__._path[0]
rev_path = os.path.join(abs_path, 'rev_*.py')
rev_names = [os.path.basename(x) for x in glob.glob(rev_path)]
if rev_id is None:
revision = rev_names[-1]
else:
revision = rev_names[rev_id]
revision = revision.split('.')[0]
# import attribute
exec(f'from {import_path}.{revision} import {attr}', globals())
一些解释:
- 显然(我不知道这一点),我们可以将文件夹作为模块导入;这个模块有一个
__path__
属性(使用内置的dir
方法找到)。 glob.glob
允许我们使用正则表达式来搜索目录中文件所需的模式。- 使用不带参数的
exec
将仅在本地命名空间(方法的命名空间)中导入,因此不会污染全局命名空间。 - 使用
exec
和globals()
允许我们在全局命名空间中导入。