Python: 确定当前实际模块(而不是__main__)

12 浏览
0 Comments

Python: 确定当前实际模块(而不是__main__)

我正在尝试确定一个函数的实际当前模块(如果从其他地方导入的话),即使当前模块是“顶级脚本环境”__main__。这听起来可能有点奇怪,但背景是我需要在不同的机器上对函数进行序列化和反序列化(包括参数),为此我需要确保在反序列化之前正确导入模块,而不是__main__(否则会出现“AttributeError: \'module\' object has no attribute my_fun”的错误)。\n到目前为止,我尝试了检查(inspection)方法:\n

import inspect
print inspect.getmodule(my_fun)

\n这当然会给我返回``。\n我还尝试使用`globals()`来找到一些有用的信息,但没有成功。\n我真正想要的是``。我想一个笨拙的方法是通过解析文件名来实现,类似于:\n

m_name = __main__.__file__.split("/")[-1].replace(".pyc","")

\n然后通过名称找到模块`sys.modules[m_name]`。\n是否有更简洁/更好的方法来做到这一点?\n编辑:\n在了解了ipython的“FakeModule”和更多的搜索后,我找到了这篇帖子,其中描述了我目前面临的确切问题,包括我目前的解决方法(明确导入当前模块`import current_module`,并序列化`current_module.my_fun`而不是my_fun)。我正在尝试避免这种方法,因为对于我包的用户来说可能不直观。

0
0 Comments

在Python中,有时候我们需要确定当前模块的实际名称,而不是使用`__main__`。下面我们来解释一下为什么会出现这个问题以及如何解决。

首先,在回顾一下,最好和最简洁的解决方法是尽量避免出现这种情况;如果是你的代码被序列化,将所有可序列化的函数移到主程序脚本加载的模块中。这样可以在任何情况下都可以找到函数的来源,而无需使用任何技巧或特殊情况。

如果这种方式不可行,我认为你最初的解决方案(通过`__main__.__file__`获取模块名称)是最好且最简单的。如果你担心这对你的用户来说似乎不直观,可以将其封装在一个好的函数中,并说明其用途。

当你将一个模块作为`__main__`运行时,Python实际上不会将其与其正常的模块名称关联起来:如果你导入模块`example`,它会再次以独立模块的形式加载文件。实际上,在你的情况下可能会发生这种情况,否则你就无法通过模块名称在`sys.modules`中找到你的模块:模块`example`和模块`__main__`实际上是不同的运行时对象,如果你在其中一个中显式更改模块变量,你会发现这一点。

为了确定当前模块的实际名称(而不是`__main__`),我们可以使用`__main__.__file__`来获取模块名称。虽然这种方式可能看起来有些不直观,但我们可以将其封装成一个函数,并添加适当的文档说明,使其更易于理解和使用。

0
0 Comments

Python中确定实际当前模块(而不是__main__)的问题是什么?原因是什么?有什么解决方法吗?

在Python中,当我们运行一个脚本时,通常会将其视为__main__模块。然而,在某些情况下,我们可能需要确定当前模块的实际名称,而不是默认的__main__。这个问题的原因是Python在获取当前模块的名称时,会返回__main__而不是实际的模块名称。

解决这个问题的方法是使用一些技巧来获取实际的模块名称。例如,可以使用以下代码来获取当前模块的实际名称:

import os
import __main__
module_name = os.path.splitext(os.path.basename(__main__.__file__))[0]

这段代码通过使用os.path模块中的函数获取__main__文件的文件名,并使用os.path.splitext函数将文件名拆分为文件名和扩展名。然后,通过取文件名的第一个部分,即[0]索引,我们可以得到实际的模块名称。

这种方法被认为是解决这个问题的最佳方法,因为它可以准确地获取当前模块的实际名称。在实际使用中,这个方法已被多个人验证,并且没有遇到任何问题。

然而,需要注意的是,如果脚本运行在一个文件夹内,这种方法可能无效。例如,如果脚本位于"bar/foo.py"文件中,使用上述方法获取的模块名称将是"foo"而不是"bar.foo"。这是因为Python在这种情况下,只返回模块的文件名部分而不考虑所在的文件夹。

总之,为了确定Python中实际的当前模块名称,我们可以使用一些技巧来获取__main__文件的文件名,并从中提取出实际的模块名称。虽然这个方法在大多数情况下都是有效的,但在特定情况下可能会出现问题。因此,在使用时需要注意这一点。

0
0 Comments

在Python中,有时我们需要确定当前模块的实际名称,而不是默认的"__main__"。有一个简单的解决方法是使用对象的__spec__属性,它存储了实际的模块名称。

下面是一个示例代码:

import inspect
if obj.__class_.__module__ == "__main__":
    print(inspect.getmodule(obj).__spec__.name)

这段代码首先通过检查对象的__class_.__module__属性来判断当前模块是否为"__main__"。如果是,则使用inspect.getmodule(obj).__spec__.name来获取实际模块的名称。

需要注意的是,这种方法只在以模块形式运行时(使用python -m命令)有效,否则__spec__属性的值为None。但对于我来说,这已经足够了!(对于我的用例来说,我可以跳过inspect并直接使用import __main__; print(__main__.__spec__.name)来实现相同的效果。)

另外,如果你在主模块中,你也可以直接使用__spec__.name来获取实际模块的名称,无需进行其他操作或导入。

总结起来,通过使用对象的__spec__属性,我们可以确定当前模块的实际名称,而不是默认的"__main__"。这在某些情况下非常有用。

0