我正在尝试从该模块内部获取模块导入的确切模块名称。像这样:
def install():
print 'Local module name is %s' % __localModuleName__
我跑的时候:
import myModule as mm
mm.install()
会打印
Local module name is mm
我正在尝试制作的脚本将自己安装到外部应用程序Maya中。 Maya在python中根据需要评估我传递的字符串。现在,我正在尝试给Maya字符串"myModule.run()"
。在这种情况下,首次运行myModule
时,我必须知道myModule.install()
的确切名称。如果用户使用__name__
导入模块,则import myModule as otherModule
不够具体。
如果有更好的方法来执行此操作而不涉及使用确切的模块名称,我很乐意知道。就像以某种方式将myModule.run
的引用转换为字符串一样,我可以将其存储在Maya中,然后解压缩。我一直在尝试使用inspect
模块来查找这些信息,但我一直在寻找不起作用的情况,我不得不再回过头来进行操作。它似乎也有点混乱。这就是我现在正在使用的内容,如果从myModule
调用__main__
,则无效。
MODULENAME = None
fr = inspect.currentframe()
try:
while fr and not MODULENAME:
if fr.f_globals:
for name, obj in fr.f_globals.iteritems():
if hasattr(obj, '__file__') and inspect.ismodule(obj) and obj.__file__ == __file__:
MODULENAME = name
fr = fr.f_back
except:
pass
finally:
del fr
如果没有好的解决方案,我打算删除上述内容,并告诉用户使用import myModule as ...
无法导入我的模块。
答案 0 :(得分:1)
这种方法可行的唯一方法就是:
import some.plugin as wanna_have
wanna_have.install(globals(), "wanna_have")
为什么?您需要两者导入模块的命名空间和导入的模块,第一个要求您传递globals()。防止这种情况的唯一方法是在install()方法中 up 一个堆栈帧,假设调用代码具有别名。当您使用签名install(importer=None, imported=__name__)
时,需要传递所有内容可以简化为使用“as”时的情况,或者调用者不是一个帧。
答案 1 :(得分:0)
我提出以下解决方案:
print 'Local module name is %s'%[key for key in vars() if 'myModule' in str(vars()[key])][0]
[0] - 这是为了防止您的模块以不同的名称多次导入,而您只需拿起第一个。如果您的模块未导入,则会出现“IndexError:list index out of range”,我认为您可以自行处理。
我用
尝试了import numpy as np
然后我应用了上面提到的oneliner:
print 'Local module name is %s',[key for key in vars() if 'numpy' in str(vars()[key])][0]
得到结果:
Local module name is np
答案 2 :(得分:0)
接近你正在尝试的方法应该有效 - 但是你可以验证它会被卷入。
此外,“import module as othername”语法只是将模块对象双向绑定到另一个变量的方便方法。
它只相当于
import module
othername = module
del module
你的代码不应该依赖于它来运行。
但是,在全局sys.modules
字典中,您的模块始终显示其“真实”名称。因此,如果您可以将字符串中的表达式传递给宿主应用程序,则应该尝试访问该字典中的模块 - 更不用说复杂了。
而不是传递:
guessedname.run()
尝试传递:
__import__("sys").modules["<module_name>"].run()
并不关心在运行代码中引用模块的变量名称。 (这甚至允许用户为您的代码执行from module import *
。