1

我知道这听起来不像 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()

编辑:包括示例代码。

4

2 回答 2

1

看起来您的代码假定该.create()函数是由您的函数的直接/直接调用者调用的(如果有的话)(您只显示部分,很难确定发生了什么)并且结果放在全局变量(函数调用者所在的模块)。这一切似乎都很脆弱。那个第三方模块不是有一些自己的全局变量会受到模块create是否被调用的影响吗?我想它会——它还会在哪里保留由执行导致的状态变化create——我会探索一下。

为了解决您提出的特定问题,

我不确定如何获取主程序定义的变量名称

that's easy -- the main program is found, as a module, in sys.modules['__main__'], so just use vars(sys.modules['__main__']) to get the global dictionary of the main program (the variable names are the keys in that dictionary, along of course with names of functions, classes, etc -- the module, like any other module, has exactly one top-level/global namespace, not one for variables, a separate one for functions, etc).

于 2010-02-25T20:00:52.803 回答
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调用时会发生变化的参数。

除非这样,并且除非有可能培训用户 import 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()
于 2010-02-25T19:27:29.990 回答