[英]Better solution than if __name__ == '__main__' twice in Python script
I have multiple Python scripts which use docopt.我有多个使用 docopt 的 Python 脚本。
My issue is that the available options for the two scripts differ slightly - one option is present in one script, but not the other.我的问题是这两个脚本的可用选项略有不同 - 一个选项存在于一个脚本中,而不存在于另一个脚本中。
I've included a minimum working example below.我在下面包含了一个最低限度的工作示例。
If I run:如果我运行:
python main.py --num=7 --name=John
the script does not run, as --name=John is also passed to module1.py, where it is not a valid option.脚本不会运行,因为 --name=John 也被传递到 module1.py,在那里它不是一个有效的选项。
With my actual script, I have several imports after docopt parses the arguments, and so I cannot simply move the docopt call to the bottom of the script ( if __name__ == '__main__':
).对于我的实际脚本,在 docopt 解析参数后我有几个导入,所以我不能简单地将 docopt 调用移动到脚本的底部(
if __name__ == '__main__':
)。 If I do this, the imports in the imported script never get called, and I get undefined name errors.如果我这样做,导入脚本中的导入永远不会被调用,并且我会收到未定义的名称错误。
I have found a workaround, but I don't think it is good practice at all.我找到了一种解决方法,但我认为这根本不是一个好习惯。
What I am doing is adding:我正在做的是添加:
if __name__ == '__main__':
arguments = docopt.docopt(__doc__, version=0.1)
just after the import docopt
.就在
import docopt
。
However, I believe that having two of these statements in a script is bad practice.但是,我认为在脚本中包含其中两个语句是不好的做法。 I cannot think of any other workarounds at this time though.
不过,我目前想不出任何其他解决方法。
Can someone suggest a better solution?有人可以提出更好的解决方案吗? Thanks in advance.
提前致谢。
main.py主文件
"""
main.py
Usage:
main.py [--num=<num>] [--name=<name>] [--lib=<lib-dir>]
main.py -h | --help
main.py --version
Options:
--num=<num> A number
--name=<name> A name
--lib=<lib-dir> Path to the directory containing lib
--version
"""
import docopt
arguments = docopt.docopt(__doc__, version=0.1)
library_path = os.path.abspath(arguments['--lib'])
sys.path.insert(1, library_path)
NUM = arguments['--num']
from other_file import x, y
from module1 import function
def main():
print 'In main()'
function()
print NUM
if __name__ == '__main__':
print '{} being executed directly'.format(__name__)
main()
module1.py:模块1.py:
"""
module1.py
Usage:
module1.py [--num=<num>] [--lib=<lib-dir>]
module1.py -h | --help
module1.py --version
Options:
--num=<num> A number
--lib=<lib-dir> Path to the directory containing lib
--version
"""
import docopt
arguments = docopt.docopt(__doc__, version=0.1)
library_path = os.path.abspath(arguments['--lib'])
sys.path.insert(1, library_path)
NUM = arguments['--num']
from other_file import z
def main():
print 'In main()'
print NUM
def function():
print 'In function in {}'.format(__name__)
# print NUM
if __name__ == '__main__':
print '{} being executed directly'.format(__name__)
main()
EDIT:编辑:
I forgot to mention that the other_file module has many different versions.我忘了提到 other_file 模块有许多不同的版本。 Because of this, one of the docopt options is the path to the file.
因此,docopt 选项之一是文件的路径。 This is then added to sys.path as follows:
然后将其添加到 sys.path 中,如下所示:
library_path = os.path.abspath(arguments['--lib'])
sys.path.insert(1, library_path)
For this reason, the import of docopt in the global scope is needed to add the path to the other_file module to my system path.为此,需要在全局范围内导入 docopt 才能将 other_file 模块的路径添加到我的系统路径中。
The global variable (NUM below, DEBUG in my actual file) I can live without.全局变量(下面的 NUM,在我的实际文件中调试)我可以没有。
The clean solution is to refactor your code so it doesn't rely on a global, neither in main.py
nor module1.py
:干净的解决方案是重构您的代码,使其不依赖于全局,无论是在
main.py
还是module1.py
:
"""
main.py
Usage:
main.py [--num=<num>] [--name=<name>]
main.py -h | --help
main.py --version
Options:
--num=<num> A number
--name=<name> A name
--version
"""
from other_file import x, y
from module1 import function
def main(num):
print 'In main()'
function(num)
print num
if __name__ == '__main__':
import docopt
arguments = docopt.docopt(__doc__, version=0.1)
NUM = arguments['--num']
print '{} being executed directly'.format(__name__)
main(NUM)
And:和:
"""
module1.py
Usage:
module1.py [--num=<num>]
module1.py -h | --help
module1.py --version
Options:
--num=<num> A number
--version
"""
from other_file import z
def main(num):
print 'In main()'
print num
def function(num):
print 'In function in {}'.format(__name__)
print num
if __name__ == '__main__':
import docopt
arguments = docopt.docopt(__doc__, version=0.1)
NUM = arguments['--num']
print '{} being executed directly'.format(__name__)
main(NUM)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.