独立运行python包子模块进行自检;导入路径混乱

独立运行python包子模块进行自检;导入路径混乱,python,Python,我经常在模块的底部编写自检代码,即 if __name__ == '__main__': . . . 我想把它保存在模块中,这样如果我修改它,我仍然可以对它运行自检。该模块是软件包的一部分。因此,存在需要解决的包间引用;但是,如果我导入包而不是单独运行模块,这些问题的解决方式就不同了 在我的模块顶部,我最终遇到了这样一个乱七八糟的问题,这肯定是丑陋的,可能不是“pythonic”: if __name__ == '__main__': from CovSample import C

我经常在模块的底部编写自检代码,即

if __name__ == '__main__':

.
.
.
我想把它保存在模块中,这样如果我修改它,我仍然可以对它运行自检。该模块是软件包的一部分。因此,存在需要解决的包间引用;但是,如果我导入包而不是单独运行模块,这些问题的解决方式就不同了

在我的模块顶部,我最终遇到了这样一个乱七八糟的问题,这肯定是丑陋的,可能不是“pythonic”:

if __name__ == '__main__':

    from CovSample import CovSample
    from ArrayByRow import ArrayByRow    
else:

    from CEOpt import CovSample
    from CEOpt import ArrayByRow
如果我导入包CEOpt,else分支引用工作,如果我独立运行,直接模块名导入工作。但这并不完美,我希望为仍然在独立模块测试中工作的包间调用提供一个导入语句。这可能吗?

没有通用的方法在这两种情况下都有效,
\uuuuuu name\uuuuu==“uuuuu main\uuuuuu”
\uuuu name!=”__主菜单

我要做的是:在每个子模块内定义一个
Test()
函数(因此
CEOpt.CovSample.Test()
CEOpt.ArrayByRow.Test()
)。然后创建一个
CEOpt/\uuuuuu main\uuuuu.py
文件,这是
CEOpt
包中唯一一个您将直接“运行”的文件(该特定文件名确保当您在shell中说
python-m CEOpt
时,它就是运行的文件名)。此文件必须按名称显式导入CEOpt,但至少现在必须只在一个位置发生(其他文件可以使用带有前缀点语法的相对导入,例如
from.CovArray import CovArray
)。现在编程
\uuu main\uuuuuuuupy
的逻辑,以便它响应通过
sys.argv
传入的子命令,选择要运行的子模块的
Test()
函数

例如,语法
python-mceopt-test-CovArray
(或者相当于
%从IPython提示符运行CEOpt/\uuuu-main\uuuuu-test-CovArray
)将触发
\uu-main\uuuuuuuuuuuuy.py
调用
CEOpt.CovArray.test()
,这两种情况下都没有通用的方法,
\uuuuu name\uuuuu==''uuuuu main\uuuuuu'
\uuuu name\uuuuuuu!='__主菜单

我要做的是:在每个子模块内定义一个
Test()
函数(因此
CEOpt.CovSample.Test()
CEOpt.ArrayByRow.Test()
)。然后创建一个
CEOpt/\uuuuuu main\uuuuu.py
文件,这是
CEOpt
包中唯一一个您将直接“运行”的文件(该特定文件名确保当您在shell中说
python-m CEOpt
时,它就是运行的文件名)。此文件必须按名称显式导入CEOpt,但至少现在必须只在一个位置发生(其他文件可以使用带有前缀点语法的相对导入,例如
from.CovArray import CovArray
)。现在编程
\uuu main\uuuuuuuupy
的逻辑,以便它响应通过
sys.argv
传入的子命令,选择要运行的子模块的
Test()
函数


因此,例如,语法
python-mceopt-test-CovArray
(或者相当于
%run-CEOpt/\uuuu-main\uuuu-test-CovArray
,从IPython提示符运行CEOpt/\uuuu-main\uuuuuu-test-CovArray)将触发
\uu-main\uuuuuuuuuuuuuuuuuuuuuuuy.py
调用
CEOpt.copt.test()(即,无需明确命名
CEOpt
)使用前缀点明确相对性:
from.CovSample import CovSample
from.ArrayByRow import ArrayByRow
。但是,当
\uu name\uuuu==“\uu main\uuuuuu”
时,这也不起作用,因此它不会回答您的问题。我也很想知道是否有一种通用的方法。请注意cer在包内导入的方法是相对地进行导入(即不必显式地命名
CEOpt
)使用前缀点明确相对性:
from.CovSample import CovSample
from.ArrayByRow import ArrayByRow
。但是,当
\uuu name\uuuu===“uuu main\uuuuuu”
时,这也不起作用,因此它不会回答您的问题。我也很想知道是否有一种通用的方法。谢谢-这就是这是一个很好的方法。在我的情况下——我通常开发一个模块,然后后来决定将其放在一个包中。因此,我有几周或几个月的时间,模块必须在没有包开销的情况下运行——然后我将其放在包中。如果我从一开始就知道我正在制作一个包,那么你的方法将对我有效。我可能不得不与我的kludge或开始计划我的工作!也许你仍然可以从一开始就将测试代码放入
test()
,但要养成说
import thing;thing.test()
而不是
run thing
。或者你可以创建自己的IPython magic
%runtest
,执行
importlib.reload(importlib.import_module(targetModuleName)).Test()
在命名目标(子)上模块。然后,您只需键入
%runtest CovArray
——或者,在以后的开发中键入
%runtest CEOpt.CovArray
,谢谢——这是一种很好的方法。在我的情况下,我通常会开发一个模块,然后在以后决定将其放在一个包中。因此,我有几周或几个月的时间,模块必须在没有包的情况下运行头部-然后我将其放入包中。如果我从一开始就知道我正在制作一个包,那么你的方法将对我有效。我可能不得不忍受我的困境,或者开始计划我的工作!也许你仍然可以从一开始就将测试代码放入
test()
,但要养成说
导入东西;东西.test()的习惯
而不是
运行东西
。或者您可以创建自己的IPython magic
%runtest
,执行
导入lib.reload(导入lib.import_模块(targetModuleName