2

docopt を使用する複数の Python スクリプトがあります。

私の問題は、2 つのスクリプトで使用できるオプションがわずかに異なることです。1 つのオプションは 1 つのスクリプトに存在しますが、もう 1 つのスクリプトには存在しません。

以下に最小限の作業例を含めました。

私が実行した場合:

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

ただし、スクリプトにこれらのステートメントを 2 つ含めることは、悪い習慣だと思います。ただし、現時点では他の回避策は考えられません。

誰かがより良い解決策を提案できますか? 前もって感謝します。

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:

"""
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 オプションの 1 つがファイルへのパスです。これは、次のように sys.path に追加されます。

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

このため、システム パスに other_file モジュールへのパスを追加するには、グローバル スコープで docopt をインポートする必要があります。

グローバル変数 (下の NUM、実際のファイルの DEBUG) なしで生活できます。

4

1 に答える 1

2

クリーンな解決策は、コードをリファクタリングして、グローバルに依存しないようにする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)
于 2015-11-27T12:09:12.187 に答える