如果主程序使用特定变量,我如何在我的模块中找出?

时间:2010-02-25 19:17:52

标签: python global-variables python-module

我知道这听起来并不像Pythonic,但是请耐心等一下。

我正在编写一个依赖于某些外部闭源模块的模块。该模块需要实例化才能使用(使用module.create())。

我的模块试图弄清楚我的用户是否已经加载了该模块(易于操作),但随后需要确定模块是否已实例化。我知道检查每个变量的type()可以告诉我这个,但我不知道如何获得主程序定义的变量名称。原因是当一个实例化模型时,它们还设置了一堆我不想因任何原因而覆盖的参数。

到目前为止,我的尝试涉及使用sys._getframe()。f_globals并迭代元素,但在我的测试中它不起作用。如果我将模块实例化为modInst然后在我的模块中调用该函数,则无法显示modInst变量。还有另一个解决方案吗?示例代码如下。

import sys
if moduleName not in sys.modules:
    import moduleName
    modInst = moduleName.create()
else:
    globalVars = sys._getframe().f_globals
    for key, value in globalVars:
        if value == "Module Name Instance":
            return key
    return moduleName.create()

编辑:包含示例代码。

2 个答案:

答案 0 :(得分:1)

看起来你的代码假设你的函数的直接/直接调用者调用了.create()函数(如果有的话)(你只是部分地显示它,很难确定发生了什么) )结果放在全局变量中(函数调用者所在的模块)。这一切看起来都很脆弱。这个第三方模块是否有一些自己的全局变量受模块的create是否被调用的影响?我想它会 - 在其他地方保持执行create导致的状态变化 - 我会探索它。

要解决您提出的具体问题,

  

我不确定如何获得这些名字   主要定义的变量   程序

这很简单 - 作为一个模块,在sys.modules['__main__']中找到主程序,所以只需使用vars(sys.modules['__main__'])来获取主程序的全局字典(变量名是其中的键)字典,当然还有函数,类等的名称 - 模块和任何其他模块一样,具有完全一个顶级/全局命名空间,不是一个用于变量,另一个用于函数等等。)

答案 1 :(得分:0)

假设外部闭源模块被称为extmod。 创建my_extmod.py

import extmod
INSTANTIATED=False
def create(*args,**kw):
    global INSTANTIATED
    INSTANTIATED=True
    return extmod.create(*args,**kw)

然后要求您的用户直接导入my_extmod而不是extmod。 要测试是否已调用create函数,只需检查extmod.INSTANTIATED的值。

编辑:如果您打开IPython会话并输入import extmod,请键入 extmod.[TAB],然后您将看到extmod命名空间中的所有顶级变量。这可能有助于您找到一些在调用extmod.create时更改的参数。

除非这样做,并且禁止培训用户导入my_extmod的可能性,否则您可能会使用类似下面的功能。 find_extmod_instance搜索sys.modules中的所有模块。

def find_instance(cls):
    for modname in sys.modules:
        module=sys.modules[modname]
        for value in vars(module).values():
            if isinstance(value,cls):
                return value

x=find_instance(extmod.ExtmodClass) or extmod.create()