[英]How can I figure out in my module if the main program uses a specific variable?
I know this does not sound Pythonic, but bear with me for a second. 我知道这听起来不像Pythonic,但请耐心等待一秒钟。
I am writing a module that depends on some external closed-source module. 我正在编写一个依赖于某些外部封闭源模块的模块。 That module needs to get instantiated to be used (using module.create()).
该模块需要实例化才能使用(使用module.create())。
My module attempts to figure out if my user already loaded that module (easy to do), but then needs to figure out if the module was instantiated. 我的模块尝试确定用户是否已经加载了该模块(易于执行),但是随后需要确定该模块是否已实例化。 I understand that checking out the type() of each variable can tell me this, but I am not sure how I can get the names of variables defined by the main program.
我知道检查每个变量的type()可以告诉我这一点,但是我不确定如何获取主程序定义的变量名。 The reason for this is that when one instantiates the model, they also set a bunch of parameters that I do not want to overwrite for any reason.
这样做的原因是,当实例化模型时,他们还设置了一堆我不想出于任何原因覆盖的参数。
My attempts so far involved using sys._getframe().f_globals and iterating through the elements, but in my testing it doesn't work. 到目前为止,我的尝试涉及使用sys._getframe()。f_globals并遍历元素,但是在我的测试中,它不起作用。 If I instantiate the module as modInst and then call the function in my module, it fails to show the modInst variable.
如果我将模块实例化为modInst,然后在我的模块中调用该函数,则它将无法显示modInst变量。 Is there another solution to this?
还有其他解决方案吗? Sample code provided below.
下面提供了示例代码。
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()
EDIT: Sample code included. 编辑:包括示例代码。
Looks like your code assumes that the .create()
function was called, if at all, by the immediate/direct caller of your function (which you show only partially, making it pretty hard to be sure about what's going on) and the results placed in a global variable (of the module where the caller of your function resides). 看起来您的代码假定
.create()
函数.create()
如果有的话.create()
是由函数的直接/直接调用者调用的(只显示了一部分,很难确定发生了什么) 和结果放在全局变量(函数调用者所在模块的全局变量)中。 It all seems pretty fragile. 一切似乎都很脆弱。 Doesn't that third-party module have some global variables of its own that are affected by whether the module's
create
has been called or not? 该第三方模块是否不具有自己的某些全局变量,这些全局变量会受到是否已调用该模块的
create
影响? I imagine it would -- where else is it keeping the state-changes resulting from executing the create
-- and I would explore that. 我想它会-还能将执行
create
所导致的状态更改保持在其他位置-我将对此进行探讨。
To address a specific issue you raise, 为了解决您提出的特定问题,
I am not sure how I can get the names of variables defined by the main program
我不确定如何获取主程序定义的变量名称
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). 这很容易-在
sys.modules['__main__']
找到作为模块的sys.modules['__main__']
,因此只需使用vars(sys.modules['__main__'])
即可获取主程序的全局字典(变量名称是该字典中的键,当然还有函数,类等的名称-该模块与其他任何模块一样,恰好具有一个顶级/全局名称空间,没有一个用于变量,一个用于函数,等等)。
Suppose the external closed-sourced module is called extmod
. 假设外部封闭源模块称为
extmod
。 Create my_extmod.py
: 创建
my_extmod.py
:
import extmod
INSTANTIATED=False
def create(*args,**kw):
global INSTANTIATED
INSTANTIATED=True
return extmod.create(*args,**kw)
Then require your users to import my_extmod
instead of extmod
directly. 然后要求您的用户直接导入
my_extmod
而不是extmod
。 To test if the create
function has been called, just check the value of extmod.INSTANTIATED
. 要测试是否已调用
create
函数,只需检查extmod.INSTANTIATED
的值。
Edit: If you open up an IPython session and type import extmod
, then type extmod.[TAB]
, then you'll see all the top-level variables in the extmod
namespace. 编辑:如果打开IPython会话并输入
import extmod
,然后输入extmod.[TAB]
,那么您将在extmod
命名空间中看到所有顶级变量。 This might help you find some parameter that changes when extmod.create
is called. 这可能有助于您找到调用
extmod.create
会更改的某些参数。
Barring that, and barring the possibility of training users to import my_extmod
, then perhaps you could use something like the function below. 禁止这种情况,并禁止培训用户导入
my_extmod
,那么也许您可以使用下面的函数。 find_extmod_instance
searches through all modules in sys.modules
. 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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.