gpt4 book ai didi

python - 将变量设置为导入它的模块的名称

转载 作者:行者123 更新时间:2023-11-30 23:08:16 24 4
gpt4 key购买 nike

假设我有两个模块:

first.package.module

# Assign module to a variable
which_module = ???

print("I originally live in {}".format(__name__)) # Prints first.package.module
print("I was run from {}".format(which_module))

第二个.package.module

from first.package.module import *

第三个.package.module

from first.package.module import *

如何让第二行“I was run from”在导入 secondary.package.module 后打印 second.package.module ?或者从那里运行时third.package.module

我想要这种行为的原因是由于在 Django 中构建了一个应用程序,该应用程序在同一项目中多次使用,即同一应用程序有多个实例。每个实例都有自己的模型,这些模型继承自抽象模型。为了构建可重用的 View 和 URL,我想动态加载模型,为此,我需要知道哪个模块导入了应用程序并运行它。

最佳答案

您可以打印触发模块加载的模块名称:

import sys

print sys._getframe(1).f_globals['__name__']

在 Python 3 中,新的 importlib您需要将帧数增加到 6(至少对于 3.5、3.6 和 3.7):

print(sys._getframe(6).f_globals['__name__'])

跨 CPython 解决方案是过滤掉任何 importlib._bootstrap*堆栈中的元素:

import sys

def imported_from(depth=0):
# skip the frames of this function, and the caller
f = sys._getframe(2 + depth)
while f and f.f_code.co_filename.startswith("<frozen importlib._bootstrap"):
f = f.f_back
return f and f.f_globals['__name__']

print(imported_from())

以上imported_from()函数可以在实用程序模块中定义并导入; sys._getframe(2)调用确保起始上下文是触发 imported_from() 的任何内容。称呼。提供一个正整数作为 depth增加跳过的帧数的参数。该函数适用于任何提供 sys._getframe() 的 Python 版本函数,无论它是否使用importlib堆栈。

请注意:

  • 依赖于 CPython 实现细节(公开帧堆栈在其他 Python 实现上不可用)。请参阅 sys._getframe() function documentation :

    CPython implementation detail: This function should be used for internal and specialized purposes only. It is not guaranteed to exist in all implementations of Python.

  • 在 Python 3 中,它取决于 importlib 的确切实现细节。堆;正在进行的开发可以添加或删除该堆栈中的调用。例如,在Python 3.3中,首先引入了importlib ,要跳过的正确堆栈计数是 9,在 3.4 中它下降到 7,而 3.5 则下降到 6(此后这个数字一直稳定)。 imported_from()解决这个问题,但引入了一个新的依赖于实现细节的假设:可以通过查找 <frozen importlib._bootstrap 来检测与导入相关的堆栈帧。文件名中的前缀。理论上可以用 importlib._bootstrap 编译 CPython未卡住(不作为 marshal 数据数组包含在解释器二进制文件中)。

  • 仅在第一次导入模块时有效,此时 Python 执行模块代码以生成 sys.modules对象。

最后一点我怎么强调都不为过。 Python 只加载一个模块一次。导入分为两步:加载和绑定(bind)。仅当模块对象尚不存在时才会执行加载步骤,模块的所有其他导入仅绑定(bind)名称

绑定(bind)名称并不是你可以实际 Hook 的东西; import modulename无非是一个modulename = sys.modules['modulename']一旦模块已经在内存中,就进行赋值。

关于python - 将变量设置为导入它的模块的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31794779/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com