如何在我的模块中确定主程序是否使用特定变量?
我知道这听起来不太 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()
编辑:包括示例代码。
I know this does not sound Pythonic, but bear with me for a second.
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()).
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. 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. If I instantiate the module as modInst and then call the function in my module, it fails to show the modInst variable. 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来您的代码假设
.create()
函数是由函数的直接/直接调用者调用的(如果有的话)(您只显示了部分内容,因此很难确定发生了什么)和放置在全局变量(函数调用者所在模块的变量)中的结果。这一切看起来都很脆弱。第三方模块是否有一些自己的全局变量,这些变量会受到模块的 create 是否被调用的影响?我想它会 - 它在哪里保存执行create
产生的状态变化 - 我会探索这一点。为了解决您提出的具体问题,
很简单——主程序作为模块在 sys.modules['__main__'] 中找到,所以只需使用 vars(sys.modules['__main__'])< /code> 获取主程序的全局字典(变量名称是该字典中的键,当然还有函数、类等的名称 - 该模块与任何其他模块一样,都有一个 顶级/全局命名空间,不是变量的命名空间,而是函数的单独命名空间,等等)。
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). 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'screate
has been called or not? I imagine it would -- where else is it keeping the state-changes resulting from executing thecreate
-- and I would explore that.To address a specific issue you raise,
that's easy -- the main program is found, as a module, in
sys.modules['__main__']
, so just usevars(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).假设外部闭源模块名为
extmod
。创建
my_extmod.py
:然后要求您的用户导入
my_extmod
而不是直接导入extmod
。要测试是否已调用
create
函数,只需检查extmod.INSTANTIATED
的值即可。编辑:如果您打开 IPython 会话并输入
import extmod
,则输入extmod.[TAB]
,然后您将看到extmod
命名空间中的所有顶级变量。这可能会帮助您找到一些在调用 extmod.create 时发生更改的参数。如果不这样做,并且不可能训练用户导入 my_extmod,那么也许您可以使用类似下面的函数。
find_extmod_instance
搜索sys.modules
中的所有模块。Suppose the external closed-sourced module is called
extmod
.Create
my_extmod.py
:Then require your users to import
my_extmod
instead ofextmod
directly.To test if the
create
function has been called, just check the value ofextmod.INSTANTIATED
.Edit: If you open up an IPython session and type
import extmod
, then typeextmod.[TAB]
, then you'll see all the top-level variables in theextmod
namespace. This might help you find some parameter that changes whenextmod.create
is called.Barring that, and barring the possibility of training users to import
my_extmod
, then perhaps you could use something like the function below.find_extmod_instance
searches through all modules insys.modules
.