繁体   English   中英

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

[英]Better solution than if __name__ == '__main__' twice in Python script

我有多个使用 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)

就在import docopt

但是,我认为在脚本中包含其中两个语句是不好的做法。 不过,我目前想不出任何其他解决方法。

有人可以提出更好的解决方案吗? 提前致谢。

主文件

"""
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,在我的实际文件中调试)我可以没有。

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

暂无
暂无

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

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