【问题标题】:Given a path to a Python source file, how do I find which package the file belongs to?给定 Python 源文件的路径,我如何找到该文件属于哪个包?
【发布时间】:2015-04-23 14:45:36
【问题描述】:

给定一个文件的路径,我需要将包名传递给importlib.import_module(),这样相对导入才能正常工作。我无法导入,然后检查module.__package__,因为它不会成功导入。

【问题讨论】:

  • 您可以添加您尝试过的内容,包括您的文件夹/文件结构吗?

标签: python packages python-importlib


【解决方案1】:

这是一种相当通用的方法:

import pathlib
import sys


def get_module_name(path):
    f = pathlib.Path(path).resolve()
    for i in map(pathlib.Path, sys.path):
        try:
            f.relative_to(i)
        except ValueError:
            pass
        else:
            *parts, fname = f.relative_to(i).parts
            return ".".join(parts), [f.stem]

module, fromlist = get_module_name("Programming/Python/kernprof.py")

print(module, fromlist)

imported_module = __import__(module, fromlist=fromlist)

print(imported_module)
print(getattr(imported_module, fromlist[0]))

输出:

Programming.Python ['kernprof']
<module 'Programming.Python' (namespace)>
<module 'Programming.Python.kernprof' from '/home/matthew/Programming/Python/kernprof.py'>

此解决方案可以处理来自sys.path 的任何路径的导入,但不能进行相对导入(sys.path 以上的导入)。 __import__的使用方法见Why does Python's __import__ require fromlist?

【讨论】:

  • 此方法有一些限制,因为它使用目录结构进行静态确定,而不处理 init.py 文件或其他方式来决定哪些文件属于哪个包,但这对我的目的来说已经足够了。
  • 是的,处理 __init__s 和 co 会非常复杂,可能会出现一些不需要的结果。
【解决方案2】:

这个助手呢?

import os


def get_parent_package(path):
    parent_path = os.path.split(path)[0]
    while parent_path != os.sep:
        if '__init__.py' in os.listdir(parent_path):
            return os.path.basename(parent_path)
        parent_path = os.path.split(parent_path)[0]
    return None

parent_path != os.sep 如果你在windows下,必须改进。

【讨论】:

  • 我发现的主要问题是,在 Python 3.3+ 中,不再需要 init.py 来定义模块,请参阅 Nick Coghlan 在@987654321 的讨论@。对于包含子包的包,自下而上遍历目录树可能会出现其他问题。
猜你喜欢
  • 1970-01-01
  • 2019-11-28
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 2016-05-12
  • 2011-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多