比在 Python 脚本中__name__ == '__main__'两次更好的解决方案



我有多个使用docopt的Python脚本。

我的问题是,这两个脚本的可用选项略有不同——一个选项出现在一个脚本中,但另一个没有。

我在下面列出了一个最低限度的工作示例。

如果我运行:

python main.py --num=7 --name=John

脚本不会运行,因为--name=John也被传递到module1.py,在那里它不是一个有效的选项。

对于我的实际脚本,在docopt解析参数后,我有几个导入,因此我不能简单地将docopt调用移动到脚本的底部(if __name__ == '__main__':)。如果我这样做,导入的脚本中的导入永远不会被调用,并且我会得到未定义的名称错误。

我找到了一个变通办法,但我认为这根本不是一个好的做法。

我正在做的是添加:

if __name__ == '__main__':
    arguments = docopt.docopt(__doc__, version=0.1)

刚好在CCD_ 2。

然而,我认为在一个脚本中包含两个这样的语句是不好的做法。不过,我现在想不出其他解决办法了。

有人能提出一个更好的解决方案吗?提前谢谢。

主.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()

模块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()

编辑:

我忘了提一下other_file模块有很多不同的版本。因此,docopt选项之一是文件的路径。然后将其添加到sys.path中,如下所示:

library_path = os.path.abspath(arguments['--lib'])
sys.path.insert(1, library_path)

因此,需要在全局作用域中导入docopt,以便将other_file模块的路径添加到我的系统路径中。

全局变量(下面的NUM,我实际文件中的DEBUG)我可以不用它。

干净的解决方案是重构代码,使其不依赖全局,无论是在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)

和:

"""
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)

相关内容

  • 没有找到相关文章