【问题标题】:Python: always import the last revision in the directoryPython:始终导入目录中的最后一个修订版
【发布时间】:2021-06-15 09:17:38
【问题描述】:

假设我们有以下数据库结构,其中数据存储在准备导入的 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)?其他想法?

【问题讨论】:

    标签: python python-3.x import


    【解决方案1】:

    我认为最好安装最后一个版本。

    但是继续你的流程,你可以在模块上使用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
    

    【讨论】:

      【解决方案2】:

      @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 只会在本地命名空间(方法的命名空间)中导入,因此不会污染全局命名空间。
      • 使用execglobals() 允许我们在全局命名空间中导入。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-15
        • 2011-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-04
        相关资源
        最近更新 更多