2017-01-23 43 views
-1

我想写一些测试python模块的包装。 这个包装模拟一个环境,然后通过execfile启动其他python模块。 有很多python模块需要测试(> 200)。防止调用子模块的全局变量在不更改submodul本身的情况下进行更改?

这些模块内部有一些硬编码的变量,它们包含一些绝对文件路径,这些文件路径在我的模拟环境中不存在(我也无法创建它们)。这些文件路径是选项文件的路径,该脚本将读入。每个模块总是只有一个选项 - 文件,并且该选项文件的文件路径始终保存在同一个全局变量中(我的意思是:变量名称在每个模块中都是相同的:optionFile)。

optionFile = "Path to Option file" 

我的想法是,我也许可以在我执行的测试模块预先设置这个全局变量“optionFile”与现有的路径。但是,这当然不会有帮助,因为执行模块在执行时会用硬编码值覆盖“optionFile”。

我想知道是否有一种方法可以覆盖globals对象的__setattr__函数,所以它对某些变量名不会做任何事情,但是我没有对我的尝试做出成功。你认为这可以工作,并有任何建议吗?

+1

模块中代码的性质是什么?如果它全部位于模块的顶层,那么你可能不太好运。也就是说,如果一个文件具有'optionFile =“/ some/path”',然后在下一行执行了'open(optionFile)',那么你就不能在'optionFile'中修改值之间。你可能会更好地运用“open”函数(或者模块用来与'optionFile'交互的任何其他函数)。 – BrenBarn

+0

好的解释:你所描述的正是python模块的性质:(。 我怎么能用open-function? ...来实现它,因为这实际上可以工作,因为这些选项文件的所有扩展名都是相同(.opt)。如果我打开函数“重新路由”所有以'.opt'结尾的文件到硬编码版本(我的替换选项文件),这可能会起作用吗? – and0r

+0

问题似乎不清楚对我而言,标题要求采取各种方法来防止变量被改变,但是主体要求改变变量的方法? – Goyo

回答

0

基于我们在这里拿到了第一印象,这似乎是不可能改变全局的__setattr__对象(虽然我不明白为什么不...)

因此,答案似乎是“没有”。

编辑
原因,为什么这不起作用,是没有全球性的“全局”对象。相反,每个模块都有其具有自己的全局变量的“个人”名称空间。该名称空间在模块加载后创建。当然可以改变这个全局命名空间 - 但是只有在模块已经被加载之后(这对我的应用场景没有帮助)。感谢BrenBarn的澄清。
编辑结束

解决我的具体描述问题的方法是改变Python的内置开放函数。

# Keep original pointer to the actual Open-function 
realOpen = open 

# Overwrite the name of the Open-function to implement own logic 
def open(filename, mode='r'): 
    if filename.endswith(".opt"): 
     print "Rerouting opening command" 
     realOpen("myCentralOptionFile.opt","r") 

    else: 
     realOpen(filename,mode) 

注意:此解决方法与标题无关。

+1

没有“全局对象”。全局变量存储在模块名称空间中。确实有可能改变这个命名空间,但问题是,直到模块被加载之后,你才能做到这一点,到那时所有的代码已经运行并完成了它想用'optionFile'完成的任何事情。你想要的只是运行模块的一部分(定义'optionFile'的部分),然后“暂停”来改变它的值,但是你不能这么做。全是或者全无:你要么运行整个模块,要么根本不运行它。 – BrenBarn

相关问题