简体   繁体   English

独立运行python package子模块进行自检; 导入路径组合

[英]Running python package sub-module independently for self-test; import path kludge

I often write self-test code at the bottom of a module, ie我经常在一个模块的底部写自检代码,即

if __name__ == '__main__':

.
.
.

I want to keep this in the module so that if I modify it I can still run self-test on it.我想把它保存在模块中,这样如果我修改它,我仍然可以在它上面运行自检。 The module is part of a package.该模块是 package 的一部分。 So there are inter-package references that need to be resolved;所以有包间引用需要解决; but these are resolved differently if I'm importing the package versus running the module standalone.但是如果我导入 package 而不是独立运行模块,这些解决方法会有所不同。

I end up with a kludge like this at the top of my modules, which is certainly ugly and probably not 'pythonic':我最终在我的模块顶部有一个这样的kludge,这肯定是丑陋的,可能不是'pythonic':

if __name__ == '__main__':

    from CovSample import CovSample
    from ArrayByRow import ArrayByRow    
else:

    from CEOpt import CovSample
    from CEOpt import ArrayByRow

This works - if I'm importing package CEOpt - the else-branch references work, and if I'm running standalone - the direct module name imports work.这有效 - 如果我正在导入 package CEOpt - else-branch 引用有效,如果我独立运行 - 直接模块名称导入有效。 But it's not pretty I would like one import statement for the inter-package calls that still work in standalone module test.但这并不漂亮我想要一个仍然在独立模块测试中工作的包间调用的导入语句。 Is that possible?那可能吗?

It seems that there's no universal way that will work in both cases, __name__=='__main__' and __name__!='__main__' . 似乎没有通用的方法适用于这两种情况, __name__=='__main__'__name__!='__main__'

What I do is the following: define a Test() function inside each submodule (so CEOpt.CovSample.Test() and CEOpt.ArrayByRow.Test() ).我所做的如下:在每个子模块内定义一个Test() function (所以CEOpt.CovSample.Test()CEOpt.ArrayByRow.Test() )。 Then create a single CEOpt/__main__.py file, which is the only file from the CEOpt package that you will ever "run" directly (that particular filename ensures that it is the one that gets run when you say python -m CEOpt from your shell).然后创建一个单一的CEOpt/__main__.py文件,它是CEOpt package 中唯一一个您将直接“运行”的文件(该特定文件名确保它是当您从您的python -m CEOpt壳)。 This file must import CEOpt explicitly by name, but at least now that only has to happen in one place (the other files can use relative imports with prefixed dot syntax—for example from.CovArray import CovArray ).该文件必须通过名称显式import CEOpt ,但至少现在只需要在一个地方发生(其他文件可以使用带有前缀点语法的相对导入,例如from.CovArray import CovArray )。 Now program the logic of __main__.py such that it responds to subcommands passed in via sys.argv , selecting which submodule's Test() function to run.现在对__main__.py的逻辑进行编程,使其响应通过sys.argv传入的子命令,选择运行哪个子模块的Test() function。

So for example, the syntax python -m CEOpt test CovArray (or equivalently %run CEOpt/__main__ test CovArray from an IPython prompt) would trigger __main__.py to call CEOpt.CovArray.Test()例如,语法python -m CEOpt test CovArray (或等效地%run CEOpt/__main__ test CovArray从 IPython 提示符)将触发__main__.py调用CEOpt.CovArray.Test()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM