【问题标题】:Fix path import when setting attribute inside imported module在导入的模块中设置属性时修复路径导入
【发布时间】:2013-10-01 01:04:58
【问题描述】:

为了让它更短,我有一个模块可以做到这一点:

MyModule
----mymodule.py
----__init__.py

mymodule.py

# Get the name of the current module
current_module = __import__(__name__)
setattr(current_module, 'VarA', 5)

因此,如果我位于 MyModule 文件夹内并打开一个 shell,则以下工作:

import mymodule
print mymodule.VarA

但如果我在 MyModule 文件夹之外进行本地化并执行以下操作:

from MyModule import mymodule
print mymodule.VarA

我得到:'module' object has no attribute 'VarA',我想这是因为setattr 正在其他地方设置VarA,所以无论我从哪里导入模块,VarA 在 mymodule 中都可用,该怎么办?

【问题讨论】:

  • mymodule.py,你为什么用setattr(..., 'VarA', 5)而不是VarA = 5

标签: python module setattr


【解决方案1】:

如果您阅读了__import__ 的文档:

name 变量为package.module 形式时,通常返回顶层包(直到第一个点的名称),不是name 命名的模块。但是,当给定一个非空的 fromlist 参数时,将返回由 name 命名的模块。

你可以很容易地看到这一点。

MyModule/mymodule.py:

current_module = __import__(__name__)
print current_module

您的程序将打印出如下内容:

<module 'MyModule' from '/Users/abarnert/src/test/pkgtest3/MyModule/__init__.pyc'>

如果您使用的是 Python 2.7,则可以略读其余文档,直到这一部分:

如果您只想按名称导入模块(可能在包中),请使用importlib.import_module()

那么,就这样做吧:

import importlib
current_module = importlib.import_module(__name__)
setattr(current_module, 'VarA', 5)

如果您需要使用早期的 2.x 版本,请阅读整个部分(对于您的 Python 版本,而不是我上面链接的 2.7)。正确的答案有点复杂,而且有点hacky:

import sys
current_package = importlib.import_module(__name__)
current_module = sys.modules[__name__]
setattr(current_module, 'VarA', 5)

当然,如果您永远不会将 MyModule/mymodule.py 作为顶级脚本运行,或者 execfile 它或在其上使用自定义导入逻辑或类似的东西,那么您不需要这种复杂性第一名。一定有人已经imported 你了,所以就这样做吧:

import sys
current_module = sys.modules[__name__]
setattr(current_module, 'VarA', 5)

当然这里最简单的解决方案是:

VarA = 5

…但大概有一个很好的理由在你的真实代码中不起作用。

【讨论】:

  • 是的,这行得通,我确实发布了一个我遇到的问题的示例,这就是为什么我将其简化为 setattr(...) 我正在将动态生成的类添加到模块中,但是你的答案是正确的。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
相关资源
最近更新 更多