简体   繁体   English

在 Python 中,如何找出哪个模块导入了特定模块

[英]In Python, how to find out which module imports a specific module

For example, I have a module called "Abc".例如,我有一个名为“Abc”的模块。 Inside Abc, I need to find out which other module imports 'Abc'.在 Abc 中,我需要找出哪个模块导入了“Abc”。 If another module called "Egf" import "Abc", is it possible to print out "Egf" inside of 'Abc'?如果另一个名为“Egf”的模块导入“Abc”,是否可以在“Abc”内打印出“Egf”? If so how?如果有怎么办?

I know a lib called https://github.com/thebjorn/pydeps/blob/master/pydeps/depgraph.py .我知道一个名为https://github.com/thebjorn/pydeps/blob/master/pydeps/depgraph.py的库。 It can build a graph by reading pyc file, but this is not what I am looking for.它可以通过读取 pyc 文件来构建图形,但这不是我想要的。

Disclaimer: This might not be a good idea and I don't know much about the internals, so I cannot guarantee that it does not break anything or works in all cases.免责声明:这可能不是一个好主意,而且我对内部结构了解不多,所以我不能保证它不会破坏任何东西或在所有情况下都有效。

  1. Imports happen only once, so if the modules Def and Ghi both include import Abc , the code in Abc will be executed just once.导入只发生一次,因此如果模块DefGhi都包含import Abc ,则Abc中的代码将只执行一次。
    • Thus we need to globally modify how imports are performed.因此,我们需要全局修改导入的执行方式。
    • import Abc evaluated to builtins.__import__("Abc", ...) , so we can override that function to check if the module to import is Abc and act accordingly. import Abc评估为builtins.__import__("Abc", ...) ,因此我们可以覆盖 function 以检查要导入的模块是否为Abc并采取相应措施。
  2. We can see the import statements in inspect.stack() , but are only provided with the filename of the import statement, not the module.我们可以在inspect.stack()中看到 import 语句,但只提供了 import 语句的文件名,而不是模块。 So if Def.py calls import Abc , we get the absolute path to Def.py , but do not know if it really is the submodule Jkl.Def .所以如果Def.py调用import Abc ,我们得到Def.py的绝对路径,但不知道它是否真的是子模块Jkl.Def
    • My answer ignores that case and just reports Def in that case.我的回答忽略了这种情况,只是在这种情况下报告Def
    • You could try this approach to get the actual module if Def is just a submodule.如果Def只是一个子模块,您可以尝试这种方法来获取实际的模块。
      1. Assuming the absolute path to be /home/testuser/modules/module1/Def.py and the actual module is module1.Def假设绝对路径为/home/testuser/modules/module1/Def.py实际模块为module1.Def
      2. Try __import__("Def") .试试__import__("Def") If it works, Def is likely to be the importing module (or there exists another module Def in the search path...)如果有效, Def很可能是导入模块(或者搜索路径中存在另一个模块Def ...)
      3. In our case that should fail, so we now call __import__("module1.Def") .在我们的例子中应该失败,所以我们现在调用__import__("module1.Def") This should succeed, so we can assume that the importing module was module1.Def .这应该会成功,因此我们可以假设导入模块是module1.Def

Abc.py abcpy

import builtins
from builtins import __import__ as builtin_import
import inspect
import os


def my_import(*args):
    """This function is intended to globally override builtins.__import__"""

    module_to_import = args[0]
    if module_to_import == "Abc":
        # for indirect imports we need to find the actual import statement in the stack
        for stackframe in inspect.stack():
            if stackframe.code_context is None:
                continue
            code = stackframe.code_context[0]
            if code.startswith(("import Abc", "from Abc")):
                # name of importing file
                importing_file = stackframe.filename  # absolute path
                importing_module = os.path.basename(importing_file).split(".")[0]
                print("Imported Abc from module", importing_module)
                break
        else:
            # This should not happen...
            print("Abc was imported but I didn't find the import statement in the stack")

    # perform the actual import
    builtin_import(*args)


# globally replace __import__
builtins.__import__ = my_import

# the first import does not use the patched __import__, so we need to do it manually
__import__("Abc")

print("I am Abc")

Def.py定义文件

import Abc
print("I am Def")

Ghi.py吉比

import Abc
print("I am Ghi")

main.py主文件

import Abc
import Def
import Ghi

Result结果

$ python3 main.py
Imported Abc from module main
I am Abc
Imported Abc from module Def
I am Def
Imported Abc from module Ghi
I am Ghi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM