[英]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.免责声明:这可能不是一个好主意,而且我对内部结构了解不多,所以我不能保证它不会破坏任何东西或在所有情况下都有效。
Def
and Ghi
both include import Abc
, the code in Abc
will be executed just once.Def
和Ghi
都包含import Abc
,则Abc
中的代码将只执行一次。
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
并采取相应措施。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
。
Def
in that case.Def
。Def
is just a submodule.Def
只是一个子模块,您可以尝试这种方法来获取实际的模块。
/home/testuser/modules/module1/Def.py
and the actual module is module1.Def
/home/testuser/modules/module1/Def.py
实际模块为module1.Def
__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
...)__import__("module1.Def")
.__import__("module1.Def")
。 This should succeed, so we can assume that the importing module was module1.Def
.module1.Def
。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")
import Abc
print("I am Def")
import Abc
print("I am Ghi")
import Abc
import Def
import Ghi
$ 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.